mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add support for custom CRC seed and polynomials.
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
//
|
//
|
||||||
// --[ Description ] ----------------------------------------------------------
|
// --[ Description ] ----------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Implements a CRC16-CCITT algorithm.
|
// Implements a CRC16 algorithm.
|
||||||
//
|
//
|
||||||
// --[ License ] --------------------------------------------------------------
|
// --[ License ] --------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@@ -37,22 +37,26 @@ using System.Text;
|
|||||||
namespace DiscImageChef.Checksums
|
namespace DiscImageChef.Checksums
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements a CRC16-CCITT algorithm
|
/// Implements a CRC16 algorithm
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Crc16Context : IChecksum
|
public class Crc16Context : IChecksum
|
||||||
{
|
{
|
||||||
const ushort CRC16_POLY = 0xA001;
|
public const ushort CRC16_IBM_POLY = 0xA001;
|
||||||
const ushort CRC16_SEED = 0x0000;
|
public const ushort CRC16_IBM_SEED = 0x0000;
|
||||||
|
public const ushort CRC16_CCITT_POLY = 0x8408;
|
||||||
|
public const ushort CRC16_CCITT_SEED = 0x0000;
|
||||||
|
|
||||||
|
readonly ushort finalSeed;
|
||||||
readonly ushort[] table;
|
readonly ushort[] table;
|
||||||
ushort hashInt;
|
ushort hashInt;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the CRC16 table and seed
|
/// Initializes the CRC16 table and seed as CRC16-IBM
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Crc16Context()
|
public Crc16Context()
|
||||||
{
|
{
|
||||||
hashInt = CRC16_SEED;
|
hashInt = CRC16_IBM_SEED;
|
||||||
|
finalSeed = CRC16_IBM_SEED;
|
||||||
|
|
||||||
table = new ushort[256];
|
table = new ushort[256];
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
@@ -60,7 +64,29 @@ 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)
|
if((entry & 1) == 1)
|
||||||
entry = (ushort)((entry >> 1) ^ CRC16_POLY);
|
entry = (ushort)((entry >> 1) ^ CRC16_IBM_POLY);
|
||||||
|
else
|
||||||
|
entry = (ushort)(entry >> 1);
|
||||||
|
|
||||||
|
table[i] = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the CRC16 table with a custom polynomial and seed
|
||||||
|
/// </summary>
|
||||||
|
public Crc16Context(ushort polynomial, ushort seed)
|
||||||
|
{
|
||||||
|
hashInt = seed;
|
||||||
|
finalSeed = seed;
|
||||||
|
|
||||||
|
table = new ushort[256];
|
||||||
|
for(int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
ushort entry = (ushort)i;
|
||||||
|
for(int j = 0; j < 8; j++)
|
||||||
|
if((entry & 1) == 1)
|
||||||
|
entry = (ushort)((entry >> 1) ^ polynomial);
|
||||||
else
|
else
|
||||||
entry = (ushort)(entry >> 1);
|
entry = (ushort)(entry >> 1);
|
||||||
|
|
||||||
@@ -93,7 +119,7 @@ namespace DiscImageChef.Checksums
|
|||||||
public byte[] Final()
|
public byte[] Final()
|
||||||
{
|
{
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
return BigEndianBitConverter.GetBytes((ushort)(hashInt ^ CRC16_SEED));
|
return BigEndianBitConverter.GetBytes((ushort)(hashInt ^ finalSeed));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -104,8 +130,8 @@ namespace DiscImageChef.Checksums
|
|||||||
StringBuilder crc16Output = new StringBuilder();
|
StringBuilder crc16Output = new StringBuilder();
|
||||||
|
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
for(int i = 0; i < BigEndianBitConverter.GetBytes((ushort)(hashInt ^ CRC16_SEED)).Length; i++)
|
for(int i = 0; i < BigEndianBitConverter.GetBytes((ushort)(hashInt ^ finalSeed)).Length; i++)
|
||||||
crc16Output.Append(BigEndianBitConverter.GetBytes((ushort)(hashInt ^ CRC16_SEED))[i].ToString("x2"));
|
crc16Output.Append(BigEndianBitConverter.GetBytes((ushort)(hashInt ^ finalSeed))[i].ToString("x2"));
|
||||||
|
|
||||||
return crc16Output.ToString();
|
return crc16Output.ToString();
|
||||||
}
|
}
|
||||||
@@ -127,10 +153,19 @@ namespace DiscImageChef.Checksums
|
|||||||
/// <param name="hash">Byte array of the hash value.</param>
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
public static string File(string filename, out byte[] hash)
|
public static string File(string filename, out byte[] hash)
|
||||||
{
|
{
|
||||||
FileStream fileStream = new FileStream(filename, FileMode.Open);
|
return File(filename, out hash, CRC16_IBM_POLY, CRC16_IBM_SEED);
|
||||||
ushort localhashInt;
|
}
|
||||||
|
|
||||||
localhashInt = CRC16_SEED;
|
/// <summary>
|
||||||
|
/// Gets the hash of a file in hexadecimal and as a byte array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">File path.</param>
|
||||||
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
|
public static string File(string filename, out byte[] hash, ushort polynomial, ushort seed)
|
||||||
|
{
|
||||||
|
FileStream fileStream = new FileStream(filename, FileMode.Open);
|
||||||
|
|
||||||
|
ushort localhashInt = seed;
|
||||||
|
|
||||||
ushort[] localTable = new ushort[256];
|
ushort[] localTable = new ushort[256];
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
@@ -138,7 +173,7 @@ 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)
|
if((entry & 1) == 1)
|
||||||
entry = (ushort)((entry >> 1) ^ CRC16_POLY);
|
entry = (ushort)((entry >> 1) ^ polynomial);
|
||||||
else
|
else
|
||||||
entry = (ushort)(entry >> 1);
|
entry = (ushort)(entry >> 1);
|
||||||
|
|
||||||
@@ -149,8 +184,9 @@ namespace DiscImageChef.Checksums
|
|||||||
localhashInt =
|
localhashInt =
|
||||||
(ushort)((localhashInt >> 8) ^ localTable[fileStream.ReadByte() ^ (localhashInt & 0xff)]);
|
(ushort)((localhashInt >> 8) ^ localTable[fileStream.ReadByte() ^ (localhashInt & 0xff)]);
|
||||||
|
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
localhashInt ^= seed;
|
||||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
|
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||||
|
|
||||||
StringBuilder crc16Output = new StringBuilder();
|
StringBuilder crc16Output = new StringBuilder();
|
||||||
|
|
||||||
@@ -169,7 +205,7 @@ namespace DiscImageChef.Checksums
|
|||||||
/// <param name="hash">Byte array of the hash value.</param>
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
public static string Data(byte[] data, uint len, out byte[] hash)
|
public static string Data(byte[] data, uint len, out byte[] hash)
|
||||||
{
|
{
|
||||||
return Data(data, len, out hash, CRC16_POLY, CRC16_SEED);
|
return Data(data, len, out hash, CRC16_IBM_POLY, CRC16_IBM_SEED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -182,9 +218,7 @@ namespace DiscImageChef.Checksums
|
|||||||
/// <param name="seed">CRC seed</param>
|
/// <param name="seed">CRC seed</param>
|
||||||
public static string Data(byte[] data, uint len, out byte[] hash, ushort polynomial, ushort seed)
|
public static string Data(byte[] data, uint len, out byte[] hash, ushort polynomial, ushort seed)
|
||||||
{
|
{
|
||||||
ushort localhashInt;
|
ushort localhashInt = seed;
|
||||||
|
|
||||||
localhashInt = seed;
|
|
||||||
|
|
||||||
ushort[] localTable = new ushort[256];
|
ushort[] localTable = new ushort[256];
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
@@ -202,8 +236,9 @@ namespace DiscImageChef.Checksums
|
|||||||
for(int i = 0; i < len; i++)
|
for(int i = 0; i < len; i++)
|
||||||
localhashInt = (ushort)((localhashInt >> 8) ^ localTable[data[i] ^ (localhashInt & 0xff)]);
|
localhashInt = (ushort)((localhashInt >> 8) ^ localTable[data[i] ^ (localhashInt & 0xff)]);
|
||||||
|
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
localhashInt ^= seed;
|
||||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
|
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||||
|
|
||||||
StringBuilder crc16Output = new StringBuilder();
|
StringBuilder crc16Output = new StringBuilder();
|
||||||
|
|
||||||
|
|||||||
@@ -41,18 +41,22 @@ namespace DiscImageChef.Checksums
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Crc32Context : IChecksum
|
public class Crc32Context : IChecksum
|
||||||
{
|
{
|
||||||
const uint CRC32_POLY = 0xEDB88320;
|
const uint CRC32_ISO_POLY = 0xEDB88320;
|
||||||
const uint CRC32_SEED = 0xFFFFFFFF;
|
const uint CRC32_ISO_SEED = 0xFFFFFFFF;
|
||||||
|
const uint CRC32_CASTAGNOLI_POLY = 0x8F6E37A0;
|
||||||
|
const uint CRC32_CASTAGNOLI_SEED = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
readonly uint finalSeed;
|
||||||
readonly uint[] table;
|
readonly uint[] table;
|
||||||
uint hashInt;
|
uint hashInt;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the CRC32 table and seed
|
/// Initializes the CRC32 table and seed as CRC32-ISO
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Crc32Context()
|
public Crc32Context()
|
||||||
{
|
{
|
||||||
hashInt = CRC32_SEED;
|
hashInt = CRC32_ISO_SEED;
|
||||||
|
finalSeed = CRC32_ISO_SEED;
|
||||||
|
|
||||||
table = new uint[256];
|
table = new uint[256];
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
@@ -60,7 +64,29 @@ 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)
|
if((entry & 1) == 1)
|
||||||
entry = (entry >> 1) ^ CRC32_POLY;
|
entry = (entry >> 1) ^ CRC32_ISO_POLY;
|
||||||
|
else
|
||||||
|
entry = entry >> 1;
|
||||||
|
|
||||||
|
table[i] = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the CRC32 table with a custom polynomial and seed
|
||||||
|
/// </summary>
|
||||||
|
public Crc32Context(uint polynomial, uint seed)
|
||||||
|
{
|
||||||
|
hashInt = seed;
|
||||||
|
finalSeed = seed;
|
||||||
|
|
||||||
|
table = new uint[256];
|
||||||
|
for(int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
uint entry = (uint)i;
|
||||||
|
for(int j = 0; j < 8; j++)
|
||||||
|
if((entry & 1) == 1)
|
||||||
|
entry = (entry >> 1) ^ polynomial;
|
||||||
else
|
else
|
||||||
entry = entry >> 1;
|
entry = entry >> 1;
|
||||||
|
|
||||||
@@ -93,7 +119,7 @@ namespace DiscImageChef.Checksums
|
|||||||
public byte[] Final()
|
public byte[] Final()
|
||||||
{
|
{
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
return BigEndianBitConverter.GetBytes(hashInt ^ CRC32_SEED);
|
return BigEndianBitConverter.GetBytes(hashInt ^ finalSeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -104,8 +130,8 @@ namespace DiscImageChef.Checksums
|
|||||||
StringBuilder crc32Output = new StringBuilder();
|
StringBuilder crc32Output = new StringBuilder();
|
||||||
|
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
for(int i = 0; i < BigEndianBitConverter.GetBytes(hashInt ^ CRC32_SEED).Length; i++)
|
for(int i = 0; i < BigEndianBitConverter.GetBytes(hashInt ^ finalSeed).Length; i++)
|
||||||
crc32Output.Append(BigEndianBitConverter.GetBytes(hashInt ^ CRC32_SEED)[i].ToString("x2"));
|
crc32Output.Append(BigEndianBitConverter.GetBytes(hashInt ^ finalSeed)[i].ToString("x2"));
|
||||||
|
|
||||||
return crc32Output.ToString();
|
return crc32Output.ToString();
|
||||||
}
|
}
|
||||||
@@ -127,10 +153,19 @@ namespace DiscImageChef.Checksums
|
|||||||
/// <param name="hash">Byte array of the hash value.</param>
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
public static string File(string filename, out byte[] hash)
|
public static string File(string filename, out byte[] hash)
|
||||||
{
|
{
|
||||||
FileStream fileStream = new FileStream(filename, FileMode.Open);
|
return File(filename, out hash, CRC32_ISO_POLY, CRC32_ISO_SEED);
|
||||||
uint localhashInt;
|
}
|
||||||
|
|
||||||
localhashInt = CRC32_SEED;
|
/// <summary>
|
||||||
|
/// Gets the hash of a file in hexadecimal and as a byte array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">File path.</param>
|
||||||
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
|
public static string File(string filename, out byte[] hash, uint polynomial, uint seed)
|
||||||
|
{
|
||||||
|
FileStream fileStream = new FileStream(filename, FileMode.Open);
|
||||||
|
|
||||||
|
uint localhashInt = seed;
|
||||||
|
|
||||||
uint[] localTable = new uint[256];
|
uint[] localTable = new uint[256];
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
@@ -138,7 +173,7 @@ 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)
|
if((entry & 1) == 1)
|
||||||
entry = (entry >> 1) ^ CRC32_POLY;
|
entry = (entry >> 1) ^ polynomial;
|
||||||
else
|
else
|
||||||
entry = entry >> 1;
|
entry = entry >> 1;
|
||||||
|
|
||||||
@@ -146,15 +181,9 @@ namespace DiscImageChef.Checksums
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) ^
|
|
||||||
localTable[fileStream.ReadByte() ^ (localhashInt & 0xff)];
|
|
||||||
if((localhashInt ^ CRC32_SEED) == 0xB883C628 ||
|
|
||||||
(localhashInt ^ CRC32_SEED) == 0x28C683B8)
|
|
||||||
System.Console.WriteLine("CRC found at position {0}", fileStream.Position);
|
|
||||||
}
|
|
||||||
|
|
||||||
localhashInt ^= CRC32_SEED;
|
localhashInt ^= seed;
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||||
|
|
||||||
@@ -175,7 +204,7 @@ namespace DiscImageChef.Checksums
|
|||||||
/// <param name="hash">Byte array of the hash value.</param>
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
public static string Data(byte[] data, uint len, out byte[] hash)
|
public static string Data(byte[] data, uint len, out byte[] hash)
|
||||||
{
|
{
|
||||||
return Data(data, len, out hash, CRC32_POLY, CRC32_SEED);
|
return Data(data, len, out hash, CRC32_ISO_POLY, CRC32_ISO_SEED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -208,7 +237,7 @@ namespace DiscImageChef.Checksums
|
|||||||
for(int i = 0; i < len; i++)
|
for(int i = 0; i < len; i++)
|
||||||
localhashInt = (localhashInt >> 8) ^ localTable[data[i] ^ (localhashInt & 0xff)];
|
localhashInt = (localhashInt >> 8) ^ localTable[data[i] ^ (localhashInt & 0xff)];
|
||||||
|
|
||||||
localhashInt ^= CRC32_SEED;
|
localhashInt ^= seed;
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||||
|
|
||||||
|
|||||||
@@ -37,22 +37,23 @@ using System.Text;
|
|||||||
namespace DiscImageChef.Checksums
|
namespace DiscImageChef.Checksums
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements a CRC64 (ECMA) algorithm
|
/// Implements a CRC64 algorithm
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Crc64Context : IChecksum
|
public class Crc64Context : IChecksum
|
||||||
{
|
{
|
||||||
const ulong CRC64_POLY = 0xC96C5795D7870F42;
|
public const ulong CRC64_ECMA_POLY = 0xC96C5795D7870F42;
|
||||||
const ulong CRC64_SEED = 0xFFFFFFFFFFFFFFFF;
|
public const ulong CRC64_ECMA_SEED = 0xFFFFFFFFFFFFFFFF;
|
||||||
|
|
||||||
|
readonly ulong finalSeed;
|
||||||
readonly ulong[] table;
|
readonly ulong[] table;
|
||||||
ulong hashInt;
|
ulong hashInt;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the CRC64 table and seed
|
/// Initializes the CRC64 table and seed as CRC64-ECMA
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Crc64Context()
|
public Crc64Context()
|
||||||
{
|
{
|
||||||
hashInt = CRC64_SEED;
|
hashInt = CRC64_ECMA_SEED;
|
||||||
|
|
||||||
table = new ulong[256];
|
table = new ulong[256];
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
@@ -60,12 +61,37 @@ 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)
|
if((entry & 1) == 1)
|
||||||
entry = (entry >> 1) ^ CRC64_POLY;
|
entry = (entry >> 1) ^ CRC64_ECMA_POLY;
|
||||||
else
|
else
|
||||||
entry = entry >> 1;
|
entry = entry >> 1;
|
||||||
|
|
||||||
table[i] = entry;
|
table[i] = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalSeed = CRC64_ECMA_SEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the CRC16 table with a custom polynomial and seed
|
||||||
|
/// </summary>
|
||||||
|
public Crc64Context(ulong polynomial, ulong seed)
|
||||||
|
{
|
||||||
|
hashInt = seed;
|
||||||
|
|
||||||
|
table = new ulong[256];
|
||||||
|
for(int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
ulong entry = (ulong)i;
|
||||||
|
for(int j = 0; j < 8; j++)
|
||||||
|
if((entry & 1) == 1)
|
||||||
|
entry = (entry >> 1) ^ polynomial;
|
||||||
|
else
|
||||||
|
entry = entry >> 1;
|
||||||
|
|
||||||
|
table[i] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalSeed = seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -93,7 +119,7 @@ namespace DiscImageChef.Checksums
|
|||||||
public byte[] Final()
|
public byte[] Final()
|
||||||
{
|
{
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
return BigEndianBitConverter.GetBytes(hashInt ^= CRC64_SEED);
|
return BigEndianBitConverter.GetBytes(hashInt ^= finalSeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -104,8 +130,8 @@ namespace DiscImageChef.Checksums
|
|||||||
StringBuilder crc64Output = new StringBuilder();
|
StringBuilder crc64Output = new StringBuilder();
|
||||||
|
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
for(int i = 0; i < BigEndianBitConverter.GetBytes(hashInt ^= CRC64_SEED).Length; i++)
|
for(int i = 0; i < BigEndianBitConverter.GetBytes(hashInt ^= finalSeed).Length; i++)
|
||||||
crc64Output.Append(BigEndianBitConverter.GetBytes(hashInt ^= CRC64_SEED)[i].ToString("x2"));
|
crc64Output.Append(BigEndianBitConverter.GetBytes(hashInt ^= finalSeed)[i].ToString("x2"));
|
||||||
|
|
||||||
return crc64Output.ToString();
|
return crc64Output.ToString();
|
||||||
}
|
}
|
||||||
@@ -127,10 +153,19 @@ namespace DiscImageChef.Checksums
|
|||||||
/// <param name="hash">Byte array of the hash value.</param>
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
public static string File(string filename, out byte[] hash)
|
public static string File(string filename, out byte[] hash)
|
||||||
{
|
{
|
||||||
FileStream fileStream = new FileStream(filename, FileMode.Open);
|
return File(filename, out hash, CRC64_ECMA_POLY, CRC64_ECMA_SEED);
|
||||||
ulong localhashInt;
|
}
|
||||||
|
|
||||||
localhashInt = CRC64_SEED;
|
/// <summary>
|
||||||
|
/// Gets the hash of a file in hexadecimal and as a byte array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">File path.</param>
|
||||||
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
|
public static string File(string filename, out byte[] hash, ulong polynomial, ulong seed)
|
||||||
|
{
|
||||||
|
FileStream fileStream = new FileStream(filename, FileMode.Open);
|
||||||
|
|
||||||
|
ulong localhashInt = seed;
|
||||||
|
|
||||||
ulong[] localTable = new ulong[256];
|
ulong[] localTable = new ulong[256];
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
@@ -138,7 +173,7 @@ 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)
|
if((entry & 1) == 1)
|
||||||
entry = (entry >> 1) ^ CRC64_POLY;
|
entry = (entry >> 1) ^ polynomial;
|
||||||
else
|
else
|
||||||
entry = entry >> 1;
|
entry = entry >> 1;
|
||||||
|
|
||||||
@@ -148,7 +183,7 @@ namespace DiscImageChef.Checksums
|
|||||||
for(int i = 0; i < fileStream.Length; i++)
|
for(int i = 0; i < fileStream.Length; i++)
|
||||||
localhashInt = (localhashInt >> 8) ^ localTable[(ulong)fileStream.ReadByte() ^ (localhashInt & 0xffL)];
|
localhashInt = (localhashInt >> 8) ^ localTable[(ulong)fileStream.ReadByte() ^ (localhashInt & 0xffL)];
|
||||||
|
|
||||||
localhashInt ^= CRC64_SEED;
|
localhashInt ^= seed;
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||||
|
|
||||||
@@ -169,7 +204,7 @@ namespace DiscImageChef.Checksums
|
|||||||
/// <param name="hash">Byte array of the hash value.</param>
|
/// <param name="hash">Byte array of the hash value.</param>
|
||||||
public static string Data(byte[] data, uint len, out byte[] hash)
|
public static string Data(byte[] data, uint len, out byte[] hash)
|
||||||
{
|
{
|
||||||
return Data(data, len, out hash, CRC64_POLY, CRC64_SEED);
|
return Data(data, len, out hash, CRC64_ECMA_POLY, CRC64_ECMA_SEED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -182,9 +217,7 @@ namespace DiscImageChef.Checksums
|
|||||||
/// <param name="seed">CRC seed</param>
|
/// <param name="seed">CRC seed</param>
|
||||||
public static string Data(byte[] data, uint len, out byte[] hash, ulong polynomial, ulong seed)
|
public static string Data(byte[] data, uint len, out byte[] hash, ulong polynomial, ulong seed)
|
||||||
{
|
{
|
||||||
ulong localhashInt;
|
ulong localhashInt = seed;
|
||||||
|
|
||||||
localhashInt = seed;
|
|
||||||
|
|
||||||
ulong[] localTable = new ulong[256];
|
ulong[] localTable = new ulong[256];
|
||||||
for(int i = 0; i < 256; i++)
|
for(int i = 0; i < 256; i++)
|
||||||
@@ -202,7 +235,7 @@ namespace DiscImageChef.Checksums
|
|||||||
for(int i = 0; i < len; i++)
|
for(int i = 0; i < len; i++)
|
||||||
localhashInt = (localhashInt >> 8) ^ localTable[data[i] ^ (localhashInt & 0xff)];
|
localhashInt = (localhashInt >> 8) ^ localTable[data[i] ^ (localhashInt & 0xff)];
|
||||||
|
|
||||||
localhashInt ^= CRC64_SEED;
|
localhashInt ^= seed;
|
||||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user