🐛Move checksum initializers to instance constructors.

This commit is contained in:
2018-02-03 17:39:49 +00:00
parent 3768e7d077
commit 28c52ef664
13 changed files with 272 additions and 252 deletions

View File

@@ -47,7 +47,7 @@ namespace DiscImageChef.Checksums
/// <summary> /// <summary>
/// Initializes the Adler-32 sums /// Initializes the Adler-32 sums
/// </summary> /// </summary>
public void Init() public Adler32Context()
{ {
sum1 = 1; sum1 = 1;
sum2 = 0; sum2 = 0;

View File

@@ -43,14 +43,14 @@ namespace DiscImageChef.Checksums
{ {
const ushort CRC16_POLY = 0xA001; const ushort CRC16_POLY = 0xA001;
const ushort CRC16_SEED = 0x0000; const ushort CRC16_SEED = 0x0000;
ushort hashInt;
ushort[] table; readonly ushort[] table;
ushort hashInt;
/// <summary> /// <summary>
/// Initializes the CRC16 table and seed /// Initializes the CRC16 table and seed
/// </summary> /// </summary>
public void Init() public Crc16Context()
{ {
hashInt = CRC16_SEED; hashInt = CRC16_SEED;
@@ -59,8 +59,10 @@ namespace DiscImageChef.Checksums
{ {
ushort entry = (ushort)i; ushort entry = (ushort)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (ushort)((entry >> 1) ^ CRC16_POLY); if((entry & 1) == 1)
else entry = (ushort)(entry >> 1); entry = (ushort)((entry >> 1) ^ CRC16_POLY);
else
entry = (ushort)(entry >> 1);
table[i] = entry; table[i] = entry;
} }
@@ -135,8 +137,10 @@ namespace DiscImageChef.Checksums
{ {
ushort entry = (ushort)i; ushort entry = (ushort)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (ushort)((entry >> 1) ^ CRC16_POLY); if((entry & 1) == 1)
else entry = (ushort)(entry >> 1); entry = (ushort)((entry >> 1) ^ CRC16_POLY);
else
entry = (ushort)(entry >> 1);
localTable[i] = entry; localTable[i] = entry;
} }
@@ -187,8 +191,10 @@ namespace DiscImageChef.Checksums
{ {
ushort entry = (ushort)i; ushort entry = (ushort)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (ushort)((entry >> 1) ^ polynomial); if((entry & 1) == 1)
else entry = (ushort)(entry >> 1); entry = (ushort)((entry >> 1) ^ polynomial);
else
entry = (ushort)(entry >> 1);
localTable[i] = entry; localTable[i] = entry;
} }

View File

@@ -43,14 +43,14 @@ namespace DiscImageChef.Checksums
{ {
const uint CRC32_POLY = 0xEDB88320; const uint CRC32_POLY = 0xEDB88320;
const uint CRC32_SEED = 0xFFFFFFFF; const uint CRC32_SEED = 0xFFFFFFFF;
uint hashInt;
uint[] table; readonly uint[] table;
uint hashInt;
/// <summary> /// <summary>
/// Initializes the CRC32 table and seed /// Initializes the CRC32 table and seed
/// </summary> /// </summary>
public void Init() public Crc32Context()
{ {
hashInt = CRC32_SEED; hashInt = CRC32_SEED;
@@ -59,8 +59,10 @@ namespace DiscImageChef.Checksums
{ {
uint entry = (uint)i; uint entry = (uint)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (entry >> 1) ^ CRC32_POLY; if((entry & 1) == 1)
else entry = entry >> 1; entry = (entry >> 1) ^ CRC32_POLY;
else
entry = entry >> 1;
table[i] = entry; table[i] = entry;
} }
@@ -135,20 +137,22 @@ namespace DiscImageChef.Checksums
{ {
uint entry = (uint)i; uint entry = (uint)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (entry >> 1) ^ CRC32_POLY; if((entry & 1) == 1)
else entry = entry >> 1; entry = (entry >> 1) ^ CRC32_POLY;
else
entry = entry >> 1;
localTable[i] = entry; localTable[i] = entry;
} }
for(int i = 0; i < fileStream.Length; i++) for(int i = 0; i < fileStream.Length; i++)
{ {
localhashInt = (localhashInt >> 8) ^ localTable[fileStream.ReadByte() ^ (localhashInt & 0xff)]; localhashInt = (localhashInt >> 8) ^
if((localhashInt ^ CRC32_SEED) == 0xB883C628 || (localhashInt ^CRC32_SEED) == 0x28C683B8) localTable[fileStream.ReadByte() ^ (localhashInt & 0xff)];
{ if((localhashInt ^ CRC32_SEED) == 0xB883C628 ||
(localhashInt ^ CRC32_SEED) == 0x28C683B8)
System.Console.WriteLine("CRC found at position {0}", fileStream.Position); System.Console.WriteLine("CRC found at position {0}", fileStream.Position);
} }
}
localhashInt ^= CRC32_SEED; localhashInt ^= CRC32_SEED;
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
@@ -193,8 +197,10 @@ namespace DiscImageChef.Checksums
{ {
uint entry = (uint)i; uint entry = (uint)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (entry >> 1) ^ polynomial; if((entry & 1) == 1)
else entry = entry >> 1; entry = (entry >> 1) ^ polynomial;
else
entry = entry >> 1;
localTable[i] = entry; localTable[i] = entry;
} }

View File

@@ -43,14 +43,14 @@ namespace DiscImageChef.Checksums
{ {
const ulong CRC64_POLY = 0xC96C5795D7870F42; const ulong CRC64_POLY = 0xC96C5795D7870F42;
const ulong CRC64_SEED = 0xFFFFFFFFFFFFFFFF; const ulong CRC64_SEED = 0xFFFFFFFFFFFFFFFF;
ulong hashInt;
ulong[] table; readonly ulong[] table;
ulong hashInt;
/// <summary> /// <summary>
/// Initializes the CRC64 table and seed /// Initializes the CRC64 table and seed
/// </summary> /// </summary>
public void Init() public Crc64Context()
{ {
hashInt = CRC64_SEED; hashInt = CRC64_SEED;
@@ -59,8 +59,10 @@ namespace DiscImageChef.Checksums
{ {
ulong entry = (ulong)i; ulong entry = (ulong)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (entry >> 1) ^ CRC64_POLY; if((entry & 1) == 1)
else entry = entry >> 1; entry = (entry >> 1) ^ CRC64_POLY;
else
entry = entry >> 1;
table[i] = entry; table[i] = entry;
} }
@@ -135,8 +137,10 @@ namespace DiscImageChef.Checksums
{ {
ulong entry = (ulong)i; ulong entry = (ulong)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (entry >> 1) ^ CRC64_POLY; if((entry & 1) == 1)
else entry = entry >> 1; entry = (entry >> 1) ^ CRC64_POLY;
else
entry = entry >> 1;
localTable[i] = entry; localTable[i] = entry;
} }
@@ -187,8 +191,10 @@ namespace DiscImageChef.Checksums
{ {
ulong entry = (ulong)i; ulong entry = (ulong)i;
for(int j = 0; j < 8; j++) for(int j = 0; j < 8; j++)
if((entry & 1) == 1) entry = (entry >> 1) ^ polynomial; if((entry & 1) == 1)
else entry = entry >> 1; entry = (entry >> 1) ^ polynomial;
else
entry = entry >> 1;
localTable[i] = entry; localTable[i] = entry;
} }

View File

@@ -47,7 +47,7 @@ namespace DiscImageChef.Checksums
/// <summary> /// <summary>
/// Initializes the Fletcher32 sums /// Initializes the Fletcher32 sums
/// </summary> /// </summary>
public void Init() public Fletcher32Context()
{ {
sum1 = 0xFFFF; sum1 = 0xFFFF;
sum2 = 0xFFFF; sum2 = 0xFFFF;

View File

@@ -34,11 +34,6 @@ namespace DiscImageChef.Checksums
{ {
public interface IChecksum public interface IChecksum
{ {
/// <summary>
/// Initializes the algorithm
/// </summary>
void Init();
/// <summary> /// <summary>
/// Updates the hash with data. /// Updates the hash with data.
/// </summary> /// </summary>

View File

@@ -46,7 +46,7 @@ namespace DiscImageChef.Checksums
/// <summary> /// <summary>
/// Initializes the MD5 hash provider /// Initializes the MD5 hash provider
/// </summary> /// </summary>
public void Init() public Md5Context()
{ {
md5Provider = MD5.Create(); md5Provider = MD5.Create();
} }

View File

@@ -46,7 +46,7 @@ namespace DiscImageChef.Checksums
/// <summary> /// <summary>
/// Initializes the RIPEMD160 hash provider /// Initializes the RIPEMD160 hash provider
/// </summary> /// </summary>
public void Init() public Ripemd160Context()
{ {
ripemd160Provider = RIPEMD160.Create(); ripemd160Provider = RIPEMD160.Create();
} }

View File

@@ -46,7 +46,7 @@ namespace DiscImageChef.Checksums
/// <summary> /// <summary>
/// Initializes the SHA1 hash provider /// Initializes the SHA1 hash provider
/// </summary> /// </summary>
public void Init() public Sha1Context()
{ {
sha1Provider = SHA1.Create(); sha1Provider = SHA1.Create();
} }

View File

@@ -46,7 +46,7 @@ namespace DiscImageChef.Checksums
/// <summary> /// <summary>
/// Initializes the SHA256 hash provider /// Initializes the SHA256 hash provider
/// </summary> /// </summary>
public void Init() public Sha256Context()
{ {
sha256Provider = SHA256.Create(); sha256Provider = SHA256.Create();
} }

View File

@@ -46,7 +46,7 @@ namespace DiscImageChef.Checksums
/// <summary> /// <summary>
/// Initializes the SHA384 hash provider /// Initializes the SHA384 hash provider
/// </summary> /// </summary>
public void Init() public Sha384Context()
{ {
sha384Provider = SHA384.Create(); sha384Provider = SHA384.Create();
} }

View File

@@ -46,7 +46,7 @@ namespace DiscImageChef.Checksums
/// <summary> /// <summary>
/// Initializes the SHA512 hash provider /// Initializes the SHA512 hash provider
/// </summary> /// </summary>
public void Init() public Sha512Context()
{ {
sha512Provider = SHA512.Create(); sha512Provider = SHA512.Create();
} }

View File

@@ -67,17 +67,13 @@ namespace DiscImageChef.Checksums
FuzzyState self; FuzzyState self;
void roll_init()
{
self.Roll = new RollState {Window = new byte[ROLLING_WINDOW]};
}
/// <summary> /// <summary>
/// Initializes the SpamSum structures /// Initializes the SpamSum structures
/// </summary> /// </summary>
public void Init() public SpamSumContext()
{ {
self = new FuzzyState {Bh = new BlockhashContext[NUM_BLOCKHASHES]}; self =
new FuzzyState {Bh = new BlockhashContext[NUM_BLOCKHASHES]};
for(int i = 0; i < NUM_BLOCKHASHES; i++) self.Bh[i].Digest = new byte[SPAMSUM_LENGTH]; for(int i = 0; i < NUM_BLOCKHASHES; i++) self.Bh[i].Digest = new byte[SPAMSUM_LENGTH];
self.Bhstart = 0; self.Bhstart = 0;
@@ -91,6 +87,50 @@ namespace DiscImageChef.Checksums
roll_init(); roll_init();
} }
/// <summary>
/// Updates the hash with data.
/// </summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of buffer to hash.</param>
public void Update(byte[] data, uint len)
{
self.TotalSize += len;
for(int i = 0; i < len; i++) fuzzy_engine_step(data[i]);
}
/// <summary>
/// Updates the hash with data.
/// </summary>
/// <param name="data">Data buffer.</param>
public void Update(byte[] data)
{
Update(data, (uint)data.Length);
}
/// <summary>
/// Returns a byte array of the hash value.
/// </summary>
public byte[] Final()
{
// SpamSum does not have a binary representation, or so it seems
throw new NotImplementedException("SpamSum does not have a binary representation.");
}
/// <summary>
/// Returns a base64 representation of the hash value.
/// </summary>
public string End()
{
FuzzyDigest(out byte[] result);
return CToString(result);
}
void roll_init()
{
self.Roll = new RollState {Window = new byte[ROLLING_WINDOW]};
}
/* /*
* a rolling hash, based on the Adler checksum. By using a rolling hash * a rolling hash, based on the Adler checksum. By using a rolling hash
* we can perform auto resynchronisation after inserts/deletes * we can perform auto resynchronisation after inserts/deletes
@@ -165,6 +205,7 @@ namespace DiscImageChef.Checksums
* blocksize. */ return; * blocksize. */ return;
if(self.Bh[self.Bhstart + 1].Dlen < SPAMSUM_LENGTH / 2) if(self.Bh[self.Bhstart + 1].Dlen < SPAMSUM_LENGTH / 2)
/* Estimate adjustment would select this blocksize. */ return; /* Estimate adjustment would select this blocksize. */ return;
/* At this point we are clearly no longer interested in the /* At this point we are clearly no longer interested in the
* start_blocksize. Get rid of it. */ * start_blocksize. Get rid of it. */
++self.Bhstart; ++self.Bhstart;
@@ -193,6 +234,7 @@ namespace DiscImageChef.Checksums
/* Once this condition is false for one bs, it is /* Once this condition is false for one bs, it is
* automatically false for all further bs. I.e. if * automatically false for all further bs. I.e. if
* h === -1 (mod 2*bs) then h === -1 (mod bs). */ break; * h === -1 (mod 2*bs) then h === -1 (mod bs). */ break;
/* We have hit a reset point. We now emit hashes which are /* We have hit a reset point. We now emit hashes which are
* based on all characters in the piece of the message between * based on all characters in the piece of the message between
* the last reset point and this one */ * the last reset point and this one */
@@ -218,26 +260,6 @@ namespace DiscImageChef.Checksums
} }
} }
/// <summary>
/// Updates the hash with data.
/// </summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of buffer to hash.</param>
public void Update(byte[] data, uint len)
{
self.TotalSize += len;
for(int i = 0; i < len; i++) fuzzy_engine_step(data[i]);
}
/// <summary>
/// Updates the hash with data.
/// </summary>
/// <param name="data">Data buffer.</param>
public void Update(byte[] data)
{
Update(data, (uint)data.Length);
}
// CLAUNIA: Flags seems to never be used in ssdeep, so I just removed it for code simplicity // CLAUNIA: Flags seems to never be used in ssdeep, so I just removed it for code simplicity
uint FuzzyDigest(out byte[] result) uint FuzzyDigest(out byte[] result)
{ {
@@ -259,6 +281,7 @@ namespace DiscImageChef.Checksums
++bi; ++bi;
if(bi >= NUM_BLOCKHASHES) throw new OverflowException("The input exceeds data types."); if(bi >= NUM_BLOCKHASHES) throw new OverflowException("The input exceeds data types.");
} }
/* Adapt blocksize guess to actual digest length. */ /* Adapt blocksize guess to actual digest length. */
while(bi >= self.Bhend) --bi; while(bi >= self.Bhend) --bi;
while(bi > self.Bhstart && self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2) --bi; while(bi > self.Bhstart && self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2) --bi;
@@ -288,7 +311,8 @@ namespace DiscImageChef.Checksums
if(remain <= 0) throw new Exception("Assertion failed"); if(remain <= 0) throw new Exception("Assertion failed");
result[resultOff] = b64[self.Bh[bi].H % 64]; result[resultOff] = b64[self.Bh[bi].H % 64];
if(i < 3 || result[resultOff] != result[resultOff - 1] || result[resultOff] != result[resultOff - 2] || if(i < 3 || result[resultOff] != result[resultOff - 1] ||
result[resultOff] != result[resultOff - 2] ||
result[resultOff] != result[resultOff - 3]) result[resultOff] != result[resultOff - 3])
{ {
++resultOff; ++resultOff;
@@ -300,7 +324,8 @@ namespace DiscImageChef.Checksums
if(remain <= 0) throw new Exception("Assertion failed"); if(remain <= 0) throw new Exception("Assertion failed");
result[resultOff] = self.Bh[bi].Digest[i]; result[resultOff] = self.Bh[bi].Digest[i];
if(i < 3 || result[resultOff] != result[resultOff - 1] || result[resultOff] != result[resultOff - 2] || if(i < 3 || result[resultOff] != result[resultOff - 1] ||
result[resultOff] != result[resultOff - 2] ||
result[resultOff] != result[resultOff - 3]) result[resultOff] != result[resultOff - 3])
{ {
++resultOff; ++resultOff;
@@ -329,7 +354,8 @@ namespace DiscImageChef.Checksums
h = self.Bh[bi].Halfh; h = self.Bh[bi].Halfh;
result[resultOff] = b64[h % 64]; result[resultOff] = b64[h % 64];
if(i < 3 || result[resultOff] != result[resultOff - 1] || if(i < 3 || result[resultOff] != result[resultOff - 1] ||
result[resultOff] != result[resultOff - 2] || result[resultOff] != result[resultOff - 3]) result[resultOff] != result[resultOff - 2] ||
result[resultOff] != result[resultOff - 3])
{ {
++resultOff; ++resultOff;
--remain; --remain;
@@ -344,7 +370,8 @@ namespace DiscImageChef.Checksums
result[resultOff] = (byte)i; result[resultOff] = (byte)i;
if(i < 3 || result[resultOff] != result[resultOff - 1] || if(i < 3 || result[resultOff] != result[resultOff - 1] ||
result[resultOff] != result[resultOff - 2] || result[resultOff] != result[resultOff - 3]) result[resultOff] != result[resultOff - 2] ||
result[resultOff] != result[resultOff - 3])
{ {
++resultOff; ++resultOff;
--remain; --remain;
@@ -367,25 +394,6 @@ namespace DiscImageChef.Checksums
return 0; return 0;
} }
/// <summary>
/// Returns a byte array of the hash value.
/// </summary>
public byte[] Final()
{
// SpamSum does not have a binary representation, or so it seems
throw new NotImplementedException("SpamSum does not have a binary representation.");
}
/// <summary>
/// Returns a base64 representation of the hash value.
/// </summary>
public string End()
{
FuzzyDigest(out byte[] result);
return CToString(result);
}
/// <summary> /// <summary>
/// Gets the hash of a file /// Gets the hash of a file
/// </summary> /// </summary>
@@ -417,7 +425,6 @@ namespace DiscImageChef.Checksums
public static string Data(byte[] data, uint len, out byte[] hash) public static string Data(byte[] data, uint len, out byte[] hash)
{ {
SpamSumContext fuzzyContext = new SpamSumContext(); SpamSumContext fuzzyContext = new SpamSumContext();
fuzzyContext.Init();
fuzzyContext.Update(data, len); fuzzyContext.Update(data, len);