Skip to content

Commit d3ad35c

Browse files
authored
Merge PR #294: Revert Adler32 changes and add test
1 parent 5d2f285 commit d3ad35c

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

src/ICSharpCode.SharpZipLib/Checksum/Adler32.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,31 @@ public void Update(byte[] buffer)
133133
/// </param>
134134
public void Update(ArraySegment<byte> segment)
135135
{
136-
foreach (byte b in segment)
136+
//(By Per Bothner)
137+
uint s1 = checkValue & 0xFFFF;
138+
uint s2 = checkValue >> 16;
139+
var count = segment.Count;
140+
var offset = segment.Offset;
141+
while (count > 0)
137142
{
138-
Update(b);
143+
// We can defer the modulo operation:
144+
// s1 maximally grows from 65521 to 65521 + 255 * 3800
145+
// s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
146+
int n = 3800;
147+
if (n > count)
148+
{
149+
n = count;
150+
}
151+
count -= n;
152+
while (--n >= 0)
153+
{
154+
s1 = s1 + (uint)(segment.Array[offset++] & 0xff);
155+
s2 = s2 + s1;
156+
}
157+
s1 %= BASE;
158+
s2 %= BASE;
139159
}
160+
checkValue = (s2 << 16) | s1;
140161
}
141162
}
142163
}

test/ICSharpCode.SharpZipLib.Tests/Checksum/ChecksumTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using ICSharpCode.SharpZipLib.Checksum;
22
using NUnit.Framework;
33
using System;
4+
using System.Diagnostics;
45

56
namespace ICSharpCode.SharpZipLib.Tests.Checksum
67
{
@@ -27,6 +28,33 @@ public void Adler_32()
2728
exceptionTesting(underTestAdler32);
2829
}
2930

31+
const long BufferSize = 256 * 1024 * 1024;
32+
33+
[Test]
34+
public void Adler_32_Performance()
35+
{
36+
var rand = new Random(1);
37+
38+
var buffer = new byte[BufferSize];
39+
rand.NextBytes(buffer);
40+
41+
var adler = new Adler32();
42+
Assert.AreEqual(0x00000001, adler.Value);
43+
44+
var sw = new Stopwatch();
45+
sw.Start();
46+
47+
adler.Update(buffer);
48+
49+
sw.Stop();
50+
Console.WriteLine($"Adler32 Hashing of 256 MiB: {sw.Elapsed.TotalSeconds:f4} second(s)");
51+
52+
adler.Update(check);
53+
Assert.AreEqual(0xD4897DA3, adler.Value);
54+
55+
exceptionTesting(adler);
56+
}
57+
3058
[Test]
3159
public void CRC_32_BZip2()
3260
{

0 commit comments

Comments
 (0)