54 Commits
1.2.0 ... 1.2.3

Author SHA1 Message Date
Matt Nadareski
98c646d579 Bump version 2024-11-06 20:38:06 -05:00
Matt Nadareski
d8da0d6312 Update test packages 2024-11-06 20:36:18 -05:00
Matt Nadareski
d259dca9ab Fix formatting in project files 2024-11-06 20:33:28 -05:00
Matt Nadareski
188483b4d1 Compress hasn't been used for a little 2024-11-06 20:24:33 -05:00
Matt Nadareski
6b33bec6e2 Remove final this reference 2024-11-06 15:23:01 -05:00
Matt Nadareski
1fc4c13683 Add testing comment 2024-11-06 15:19:57 -05:00
Matt Nadareski
2ef3a6f254 Add CRC-24 implementations 2024-11-06 14:45:19 -05:00
Matt Nadareski
827239a08a Add CRC-40 implementation 2024-11-06 14:32:17 -05:00
Matt Nadareski
c1e847c1cf Reenable RIPEMD test 2024-11-06 14:15:55 -05:00
Matt Nadareski
f01d801421 Privatize the table 2024-11-06 14:11:45 -05:00
Matt Nadareski
483a74f8c9 Add first working fast transform 2024-11-06 13:42:12 -05:00
Matt Nadareski
d0660472eb Less hardcoding, I guess? 2024-11-06 12:45:53 -05:00
Matt Nadareski
5718c62157 None of that needs to be public 2024-11-06 12:44:33 -05:00
Matt Nadareski
63eff1ab18 Outsource checksum step 2024-11-06 12:40:43 -05:00
Matt Nadareski
7de1c6464f Reduce allocated tables 2024-11-06 12:03:09 -05:00
Matt Nadareski
f900eca029 Separate checksum step into new method 2024-11-06 12:00:22 -05:00
Matt Nadareski
cb3585ae49 Rename parameter 2024-11-06 11:56:09 -05:00
Matt Nadareski
9610e1756f Add remaining CRC-16 implementations 2024-11-06 06:31:29 -05:00
Matt Nadareski
45d0e2dde1 Replace CRC-16 existing implementations 2024-11-06 05:54:41 -05:00
Matt Nadareski
389c609a9d Comments into summaries 2024-11-06 05:47:09 -05:00
Matt Nadareski
71d88d3467 Add all CRC-16 definitions 2024-11-06 05:42:22 -05:00
Matt Nadareski
3905905301 Make CRC-64/ECMA default 2024-11-06 05:21:39 -05:00
Matt Nadareski
adc03c90eb Remove Aaru CRC-32 2024-11-06 05:20:09 -05:00
Matt Nadareski
4c006317be Add remaining CRC-32 implementations 2024-11-06 05:19:13 -05:00
Matt Nadareski
21498f6d52 Remove Aaru CRC-64 2024-11-06 05:08:48 -05:00
Matt Nadareski
2dcf0e7eea Add remaining CRC-64 implementations 2024-11-06 05:08:21 -05:00
Matt Nadareski
0cf07ae13a Remove external CRC-32 implementations 2024-11-06 04:54:27 -05:00
Matt Nadareski
74d74fdfae Remove note 2024-11-06 04:52:42 -05:00
Matt Nadareski
9e48cca1a3 Add unoptimized generic CRC framework 2024-11-06 04:46:39 -05:00
Matt Nadareski
23679266b4 Finalize CRC64 support names 2024-11-06 02:54:27 -05:00
Matt Nadareski
992e22cc76 ECMA/ISO war 2024-11-06 02:34:59 -05:00
Matt Nadareski
5cfe0dcb09 Remove "CRC64_ECMA" 2024-11-06 02:21:20 -05:00
Matt Nadareski
3ebb489f23 Use correct name for implementation 2024-11-06 02:14:58 -05:00
Matt Nadareski
94b9e91718 Create and use CRC64_ECMA 2024-11-06 00:37:40 -05:00
Matt Nadareski
445c3473d9 Correct comment in README 2024-11-06 00:18:55 -05:00
Matt Nadareski
d8bc77a938 Resync CRC64 just in case 2024-11-06 00:17:10 -05:00
Matt Nadareski
10406fa90c Update seed based on MS documentation 2024-11-06 00:03:26 -05:00
Matt Nadareski
08f5ae5b8b Add TODO after way too much thinking 2024-11-06 00:02:16 -05:00
Matt Nadareski
e5010f1856 Better define polynomials 2024-11-05 23:50:25 -05:00
Matt Nadareski
d6b00b1a42 Fix build 2024-11-05 22:08:03 -05:00
Matt Nadareski
8aa10ff06b Reduce reliance on external packages 2024-11-05 22:02:30 -05:00
Matt Nadareski
7eeb11261b Bump version 2024-10-24 17:22:24 -04:00
Matt Nadareski
a0fc83b617 Add publish scripts 2024-10-24 17:21:55 -04:00
Matt Nadareski
fbc81459ee Reduce framework-dependent code 2024-10-24 17:17:39 -04:00
Matt Nadareski
7d53e07e90 Simplify internal hashing method
This may fix a bug with some compressed streams that, if no bytes were read, may cause odd issues when passed to the hashers, leading to inconsistent values.
2024-10-24 16:45:02 -04:00
Matt Nadareski
e83c31b89c Increase to 50 files in zip 2024-07-19 11:03:27 -04:00
Matt Nadareski
ca08f97336 Increase to 20 files in zip 2024-07-19 10:59:36 -04:00
Matt Nadareski
bd1e23dad4 Add gzip stream test, just in case 2024-07-19 10:54:54 -04:00
Matt Nadareski
b22f3d2743 Better documentation in tests 2024-07-19 10:50:46 -04:00
Matt Nadareski
23ed4e9849 Ensure multiple files hash correctly from archives 2024-07-19 10:47:42 -04:00
Matt Nadareski
4bc26b824f Bump version 2024-07-16 00:05:33 -04:00
Matt Nadareski
d5b0b2ad02 Don't rely on stream size; read until nothing left 2024-07-16 00:02:49 -04:00
Matt Nadareski
3fa3ece655 All unsafe setting of length in hashing 2024-07-15 23:38:12 -04:00
Matt Nadareski
87fb62d772 Start adding Tiger hash (nw) 2024-06-25 13:54:07 -04:00
38 changed files with 2825 additions and 4079 deletions

View File

@@ -4,11 +4,9 @@ This library comprises of methods and helpers to simplify the process of getting
| Source | Hash / Checksum Types | Notes |
| --- | --- | --- |
| [Aaru.Checksums](https://github.com/aaru-dps/Aaru.Checksums) | Adler-32, CRC-16 (CCITT and IBM polynomials), CRC-32, CRC-64 (Normal and Reversed Polynomials), Fletcher-16, Fletcher-32, SpamSum | Some code tweaks made to support older .NET versions, CRC-32 implementation used in `net20`, `net35`, `net40`, and `net452` |
| [Aaru.Checksums](https://github.com/aaru-dps/Aaru.Checksums) | Adler-32, Fletcher-16, Fletcher-32, SpamSum | Some code tweaks made to support older .NET versions |
| [Blake3.NET](https://github.com/xoofx/Blake3.NET) | BLAKE3 | Used in `net7.0` and above |
| [Compress](https://github.com/RomVault/RVWorld/tree/master/Compress) | N/A | Used for threaded hashing |
| [CRC32](https://gitlab.com/eugene77/CRC32) | CRC-32 (Multiple implementations) | |
| [System.IO.Hashing](https://www.nuget.org/packages/System.IO.Hashing) | CRC-32, CRC-64 (Normal Polynomial), xxHash32, xxHash64, XXH3, XXH128 | Used in `net462` and above |
| [System.IO.Hashing](https://www.nuget.org/packages/System.IO.Hashing) | xxHash32, xxHash64, XXH3, XXH128 | Used in `net462` and above |
| [System.Security.Cryptography](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography) | MD5, RIPEMD160 (.NET Framework only), SHA-1, SHA-256, SHA-384, SHA-512, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256 | Built-in library; SHA3-256, SHA3-384, SHA3-512, SHAKE128, and SHAKE256 are `net8.0` and above only for [supported platforms](https://learn.microsoft.com/en-us/dotnet/standard/security/cross-platform-cryptography) |
Find the link to the Nuget package [here](https://www.nuget.org/packages/SabreTools.Hashing).

View File

@@ -0,0 +1,58 @@
using System;
using System.IO;
using System.IO.Compression;
using Xunit;
namespace SabreTools.Hashing.Test
{
public class CompressedStreamTests
{
/// <summary>
/// Path to PKZIP archive containing a single compressed file to hash
/// </summary>
private static readonly string _singleGzipFilePath
= Path.Combine(Environment.CurrentDirectory, "TestData", "file-to-hash.bin.gz");
/// <summary>
/// Path to PKZIP archive containing a single compressed file to hash
/// </summary>
private static readonly string _singleZipFilePath
= Path.Combine(Environment.CurrentDirectory, "TestData", "file-to-hash.zip");
/// <summary>
/// Path to PKZIP archive containing a multiple compressed files to hash
/// </summary>
private static readonly string _multiZipFilePath
= Path.Combine(Environment.CurrentDirectory, "TestData", "file-to-hash-multi.zip");
[Fact]
public void GetSingleGzipStreamHashesTest()
{
var gzipStream = new GZipStream(File.OpenRead(_singleGzipFilePath), CompressionMode.Decompress);
var hashDict = HashTool.GetStreamHashes(gzipStream);
TestHelper.ValidateHashes(hashDict);
}
[Fact]
public void GetSingleDeflateStreamHashesTest()
{
var zipFile = ZipFile.OpenRead(_singleZipFilePath);
var fileStream = zipFile.Entries[0].Open();
var hashDict = HashTool.GetStreamHashes(fileStream);
TestHelper.ValidateHashes(hashDict);
}
[Fact]
public void GetMultiDeflateStreamHashesTest()
{
var zipFile = ZipFile.OpenRead(_multiZipFilePath);
for (int i = 0; i < zipFile.Entries.Count; i++)
{
var fileStream = zipFile.Entries[i].Open();
var hashDict = HashTool.GetStreamHashes(fileStream);
TestHelper.ValidateHashes(hashDict);
}
}
}
}

View File

@@ -6,44 +6,18 @@ namespace SabreTools.Hashing.Test
{
public class HashToolTests
{
private static readonly string _hashFilePath = Path.Combine(Environment.CurrentDirectory, "TestData", "file-to-hash.bin");
/// <summary>
/// Path to the uncompressed file to hash
/// </summary>
private static readonly string _hashFilePath
= Path.Combine(Environment.CurrentDirectory, "TestData", "file-to-hash.bin");
#region Known File Information
private const long _hashFileSize = 125;
private const string _adler32 = "08562d95";
#if NET7_0_OR_GREATER
private const string _blake3 = "d4bd7ca6f1ebea9580d9381106b248eb5b6069170d0bfd00b17d659fcd10dcdc";
#endif
private const string _crc16_ccitt = "482d";
private const string _crc16_ibm = "7573";
private const string _crc32 = "ba02a660";
private const string _crc64 = "a0e0009c18b5338d";
private const string _crc64_reversed = "fb49044e8331f6e5";
private const string _fletcher16 = "46c1";
private const string _fletcher32 = "073f2d94";
private const string _md5 = "b722871eaa950016296184d026c5dec9";
#if NETFRAMEWORK
private const string _ripemd160 = "346361e1d7fdb836650cecdb842b0dbe660eed66";
#endif
private const string _sha1 = "eea1ee2d801d830c4bdad4df3c8da6f9f52d1a9f";
private const string _sha256 = "fdb02dee8c319c52087382c45f099c90d0b6cc824850aff28c1bfb2884b7b855";
private const string _sha384 = "e276c49618fff25bc1fe2e0659cd0ef0e7c1186563b063e07c52323b9899f3ce9b091be04d6208444b3ef1265e879074";
private const string _sha512 = "15d69514eb628c2403e945a7cafd1d27e557f6e336c69b63ea17e7ed9d256cc374ee662f09305836d6de37fdae59d83883b982aa8446e4ff26346b6b6b50b240";
#if NET8_0_OR_GREATER
private const string _sha3_256 = "1d76459e68c865b5911ada5104067cc604c5c60b345c4e81b3905e916a43c868";
private const string _sha3_384 = "1bcbed87b73f25c0adf486c3afbf0ea3105763c387af3f8b2bd79b0a1964d42832b1d7c6a2225f9153ead26f442e8b67";
private const string _sha3_512 = "89852144df37c58d01f5912124f1942dd00bac0346eb3971943416699c3094cff087fb42c356019c3d91f8e8f55b9254c8caec48e9414af6817297d06725ffeb";
private const string _shake128 = "e5f88d0db79a71c39490beb9ebac21eaf4a5d6368438fca20f5e4ce77cfee9aa";
private const string _shake256 = "24d9e83198bbc7baf4dcd293bfc35ae3fff05399786c37318f1b1ef85f41970c66926f8a2a1f912d96e2d8e45535af88a301a1c200697437c1a65d7e980344bc";
#endif
private const string _spamsum = "3:hMCPQCE6AFQxWyENFACBE+rW6Tj7SMQmKozr9MVERkL:hZRdxZENFs+rPSromekL";
#if NET462_OR_GREATER || NETCOREAPP
private const string _xxhash32 = "8e331daa";
private const string _xxhash64 = "082bf6f0a49e1e18";
private const string _xxhash3 = "040474eb0eda9ff2";
private const string _xxhash128 = "d934b4b4a5e1e11baeef8012fbcd11e8";
#endif
#endregion
@@ -63,98 +37,15 @@ namespace SabreTools.Hashing.Test
public void GetFileHashesTest()
{
var hashDict = HashTool.GetFileHashes(_hashFilePath);
Assert.NotNull(hashDict);
Assert.Equal(_adler32, hashDict![HashType.Adler32]);
#if NET7_0_OR_GREATER
Assert.Equal(_blake3, hashDict[HashType.BLAKE3]);
#endif
Assert.Equal(_crc16_ccitt, hashDict[HashType.CRC16_CCITT]);
Assert.Equal(_crc16_ibm, hashDict[HashType.CRC16_IBM]);
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_ISO]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Naive]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Optimized]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Parallel]);
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
Assert.Equal(_crc64_reversed, hashDict[HashType.CRC64_Reversed]);
Assert.Equal(_fletcher16, hashDict[HashType.Fletcher16]);
Assert.Equal(_fletcher32, hashDict[HashType.Fletcher32]);
Assert.Equal(_md5, hashDict[HashType.MD5]);
#if NETFRAMEWORK
Assert.Equal(_ripemd160, hashDict[HashType.RIPEMD160]);
#endif
Assert.Equal(_sha1, hashDict[HashType.SHA1]);
Assert.Equal(_sha256, hashDict[HashType.SHA256]);
Assert.Equal(_sha384, hashDict[HashType.SHA384]);
Assert.Equal(_sha512, hashDict[HashType.SHA512]);
#if NET8_0_OR_GREATER
if (System.Security.Cryptography.SHA3_256.IsSupported)
Assert.Equal(_sha3_256, hashDict[HashType.SHA3_256]);
if (System.Security.Cryptography.SHA3_384.IsSupported)
Assert.Equal(_sha3_384, hashDict[HashType.SHA3_384]);
if (System.Security.Cryptography.SHA3_512.IsSupported)
Assert.Equal(_sha3_512, hashDict[HashType.SHA3_512]);
if (System.Security.Cryptography.Shake128.IsSupported)
Assert.Equal(_shake128, hashDict[HashType.SHAKE128]);
if (System.Security.Cryptography.Shake256.IsSupported)
Assert.Equal(_shake256, hashDict[HashType.SHAKE256]);
#endif
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
#if NET462_OR_GREATER || NETCOREAPP
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
#endif
TestHelper.ValidateHashes(hashDict);
}
[Fact]
public void GetFileHashesAndSizeTest()
{
var hashDict = HashTool.GetFileHashesAndSize(_hashFilePath, out long actualSize);
Assert.Equal(_hashFileSize, actualSize);
Assert.NotNull(hashDict);
Assert.Equal(_adler32, hashDict![HashType.Adler32]);
#if NET7_0_OR_GREATER
Assert.Equal(_blake3, hashDict[HashType.BLAKE3]);
#endif
Assert.Equal(_crc16_ccitt, hashDict[HashType.CRC16_CCITT]);
Assert.Equal(_crc16_ibm, hashDict[HashType.CRC16_IBM]);
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_ISO]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Naive]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Optimized]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Parallel]);
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
Assert.Equal(_crc64_reversed, hashDict[HashType.CRC64_Reversed]);
Assert.Equal(_fletcher16, hashDict[HashType.Fletcher16]);
Assert.Equal(_fletcher32, hashDict[HashType.Fletcher32]);
Assert.Equal(_md5, hashDict[HashType.MD5]);
Assert.Equal(_sha1, hashDict[HashType.SHA1]);
Assert.Equal(_sha256, hashDict[HashType.SHA256]);
Assert.Equal(_sha384, hashDict[HashType.SHA384]);
Assert.Equal(_sha512, hashDict[HashType.SHA512]);
#if NET8_0_OR_GREATER
if (System.Security.Cryptography.SHA3_256.IsSupported)
Assert.Equal(_sha3_256, hashDict[HashType.SHA3_256]);
if (System.Security.Cryptography.SHA3_384.IsSupported)
Assert.Equal(_sha3_384, hashDict[HashType.SHA3_384]);
if (System.Security.Cryptography.SHA3_512.IsSupported)
Assert.Equal(_sha3_512, hashDict[HashType.SHA3_512]);
if (System.Security.Cryptography.Shake128.IsSupported)
Assert.Equal(_shake128, hashDict[HashType.SHAKE128]);
if (System.Security.Cryptography.Shake256.IsSupported)
Assert.Equal(_shake256, hashDict[HashType.SHAKE256]);
#endif
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
#if NET462_OR_GREATER || NETCOREAPP
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
#endif
TestHelper.ValidateHashes(hashDict);
}
[Fact]
@@ -162,47 +53,7 @@ namespace SabreTools.Hashing.Test
{
byte[] fileBytes = File.ReadAllBytes(_hashFilePath);
var hashDict = HashTool.GetByteArrayHashes(fileBytes);
Assert.NotNull(hashDict);
Assert.Equal(_adler32, hashDict![HashType.Adler32]);
#if NET7_0_OR_GREATER
Assert.Equal(_blake3, hashDict[HashType.BLAKE3]);
#endif
Assert.Equal(_crc16_ccitt, hashDict[HashType.CRC16_CCITT]);
Assert.Equal(_crc16_ibm, hashDict[HashType.CRC16_IBM]);
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_ISO]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Naive]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Optimized]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Parallel]);
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
Assert.Equal(_crc64_reversed, hashDict[HashType.CRC64_Reversed]);
Assert.Equal(_fletcher16, hashDict[HashType.Fletcher16]);
Assert.Equal(_fletcher32, hashDict[HashType.Fletcher32]);
Assert.Equal(_md5, hashDict[HashType.MD5]);
Assert.Equal(_sha1, hashDict[HashType.SHA1]);
Assert.Equal(_sha256, hashDict[HashType.SHA256]);
Assert.Equal(_sha384, hashDict[HashType.SHA384]);
Assert.Equal(_sha512, hashDict[HashType.SHA512]);
#if NET8_0_OR_GREATER
if (System.Security.Cryptography.SHA3_256.IsSupported)
Assert.Equal(_sha3_256, hashDict[HashType.SHA3_256]);
if (System.Security.Cryptography.SHA3_384.IsSupported)
Assert.Equal(_sha3_384, hashDict[HashType.SHA3_384]);
if (System.Security.Cryptography.SHA3_512.IsSupported)
Assert.Equal(_sha3_512, hashDict[HashType.SHA3_512]);
if (System.Security.Cryptography.Shake128.IsSupported)
Assert.Equal(_shake128, hashDict[HashType.SHAKE128]);
if (System.Security.Cryptography.Shake256.IsSupported)
Assert.Equal(_shake256, hashDict[HashType.SHAKE256]);
#endif
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
#if NET462_OR_GREATER || NETCOREAPP
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
#endif
TestHelper.ValidateHashes(hashDict);
}
[Fact]
@@ -210,47 +61,7 @@ namespace SabreTools.Hashing.Test
{
var fileStream = File.OpenRead(_hashFilePath);
var hashDict = HashTool.GetStreamHashes(fileStream);
Assert.NotNull(hashDict);
Assert.Equal(_adler32, hashDict![HashType.Adler32]);
#if NET7_0_OR_GREATER
Assert.Equal(_blake3, hashDict[HashType.BLAKE3]);
#endif
Assert.Equal(_crc16_ccitt, hashDict[HashType.CRC16_CCITT]);
Assert.Equal(_crc16_ibm, hashDict[HashType.CRC16_IBM]);
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_ISO]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Naive]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Optimized]);
Assert.Equal(_crc32, hashDict[HashType.CRC32_Parallel]);
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
Assert.Equal(_crc64_reversed, hashDict[HashType.CRC64_Reversed]);
Assert.Equal(_fletcher16, hashDict[HashType.Fletcher16]);
Assert.Equal(_fletcher32, hashDict[HashType.Fletcher32]);
Assert.Equal(_md5, hashDict[HashType.MD5]);
Assert.Equal(_sha1, hashDict[HashType.SHA1]);
Assert.Equal(_sha256, hashDict[HashType.SHA256]);
Assert.Equal(_sha384, hashDict[HashType.SHA384]);
Assert.Equal(_sha512, hashDict[HashType.SHA512]);
#if NET8_0_OR_GREATER
if (System.Security.Cryptography.SHA3_256.IsSupported)
Assert.Equal(_sha3_256, hashDict[HashType.SHA3_256]);
if (System.Security.Cryptography.SHA3_384.IsSupported)
Assert.Equal(_sha3_384, hashDict[HashType.SHA3_384]);
if (System.Security.Cryptography.SHA3_512.IsSupported)
Assert.Equal(_sha3_512, hashDict[HashType.SHA3_512]);
if (System.Security.Cryptography.Shake128.IsSupported)
Assert.Equal(_shake128, hashDict[HashType.SHAKE128]);
if (System.Security.Cryptography.Shake256.IsSupported)
Assert.Equal(_shake256, hashDict[HashType.SHAKE256]);
#endif
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
#if NET462_OR_GREATER || NETCOREAPP
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
#endif
TestHelper.ValidateHashes(hashDict);
}
}
}

View File

@@ -1,43 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net6.0;net7.0;net8.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>net462;net472;net48;net6.0;net7.0;net8.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
</PropertyGroup>
<ItemGroup>
<None Remove="TestData\*" />
</ItemGroup>
<ItemGroup>
<None Remove="TestData\*" />
</ItemGroup>
<ItemGroup>
<Content Include="TestData\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="TestData\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<!-- Support for old .NET versions -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net462`)) OR $(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
<PackageReference Include="xunit" Version="2.6.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SabreTools.Hashing\SabreTools.Hashing.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SabreTools.Hashing\SabreTools.Hashing.csproj" />
</ItemGroup>
</Project>
</Project>

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,223 @@
using System.Collections.Generic;
using Xunit;
namespace SabreTools.Hashing.Test
{
/// <summary>
/// Helper class for tests
/// </summary>
/// CRC values confirmed with <see href="https://emn178.github.io/online-tools/crc/"/>
internal static class TestHelper
{
#region Known File Information
private const long _hashFileSize = 125;
private const string _adler32 = "08562d95";
#if NET7_0_OR_GREATER
private const string _blake3 = "d4bd7ca6f1ebea9580d9381106b248eb5b6069170d0bfd00b17d659fcd10dcdc";
#endif
private const string _crc16 = "7573";
private const string _crc16_arc = "7573";
private const string _crc16_cdma2000 = "8b5f";
private const string _crc16_cms = "1a37";
private const string _crc16_dds110 = "241d";
private const string _crc16_dectr = "7390";
private const string _crc16_dectx = "7391";
private const string _crc16_dnp = "4bbb";
private const string _crc16_en13757 = "e28b";
private const string _crc16_genibus = "b65d";
private const string _crc16_gsm = "482d";
private const string _crc16_ibm3740 = "49a2";
private const string _crc16_ibmsdlc = "4f52";
private const string _crc16_isoiec144433a = "85cd";
private const string _crc16_kermit = "bed2";
private const string _crc16_lj1200 = "3533";
private const string _crc16_m17 = "5223";
private const string _crc16_maximdow = "8a8c";
private const string _crc16_mcrf4xx = "b0ad";
private const string _crc16_modbus = "9e54";
private const string _crc16_nrsc5 = "4857";
private const string _crc16_opensafetya = "abcd";
private const string _crc16_opensafetyb = "76f4";
private const string _crc16_profibus = "3099";
private const string _crc16_riello = "23e0";
private const string _crc16_spifujitsu = "f98b";
private const string _crc16_t10dif = "2642";
private const string _crc16_teledisk = "7e05";
private const string _crc16_tms37157 = "dba0";
private const string _crc16_umts = "fee0";
private const string _crc16_usb = "61ab";
private const string _crc16_xmodem = "b7d2";
private const string _crc24_ble = "2969f2";
private const string _crc24_flexraya = "ce9dc7";
private const string _crc24_flexrayb = "0f49d7";
private const string _crc24_interlaken = "fb4725";
private const string _crc24_ltea = "675e55";
private const string _crc24_lteb = "c91203";
private const string _crc24_openpgp = "0c6012";
private const string _crc24_os9 = "610e21";
private const string _crc32 = "ba02a660";
private const string _crc32_aixm = "6174a75a";
private const string _crc32_autosar = "c050428e";
private const string _crc32_base91d = "e741ba25";
private const string _crc32_bzip2 = "18aa4603";
private const string _crc32_cdromedc = "b8ced467";
private const string _crc32_cksum = "f27b3c27";
private const string _crc32_iscsi = "544d37db";
private const string _crc32_isohdlc = "ba02a660";
private const string _crc32_jamcrc = "45fd599f";
private const string _crc32_mef = "d9d98444";
private const string _crc32_mpeg2 = "e755b9fc";
private const string _crc32_xfer = "55bdf222";
private const string _crc40_gsm = "c9843306eb";
private const string _crc64 = "8d33b5189c00e0a0";
private const string _crc64_ecma182 = "8d33b5189c00e0a0";
private const string _crc64_goiso = "6c3bf747ccfa1e3b";
private const string _crc64_ms = "799edc0db430d7be";
private const string _crc64_nvme = "9242023bbcf6bbf9";
private const string _crc64_redis = "408dab12b9f45dad";
private const string _crc64_we = "91812be748f941c4";
private const string _crc64_xz = "fb49044e8331f6e5";
private const string _fletcher16 = "46c1";
private const string _fletcher32 = "073f2d94";
private const string _md5 = "b722871eaa950016296184d026c5dec9";
#if NETFRAMEWORK
private const string _ripemd160 = "346361e1d7fdb836650cecdb842b0dbe660eed66";
#endif
private const string _sha1 = "eea1ee2d801d830c4bdad4df3c8da6f9f52d1a9f";
private const string _sha256 = "fdb02dee8c319c52087382c45f099c90d0b6cc824850aff28c1bfb2884b7b855";
private const string _sha384 = "e276c49618fff25bc1fe2e0659cd0ef0e7c1186563b063e07c52323b9899f3ce9b091be04d6208444b3ef1265e879074";
private const string _sha512 = "15d69514eb628c2403e945a7cafd1d27e557f6e336c69b63ea17e7ed9d256cc374ee662f09305836d6de37fdae59d83883b982aa8446e4ff26346b6b6b50b240";
#if NET8_0_OR_GREATER
private const string _sha3_256 = "1d76459e68c865b5911ada5104067cc604c5c60b345c4e81b3905e916a43c868";
private const string _sha3_384 = "1bcbed87b73f25c0adf486c3afbf0ea3105763c387af3f8b2bd79b0a1964d42832b1d7c6a2225f9153ead26f442e8b67";
private const string _sha3_512 = "89852144df37c58d01f5912124f1942dd00bac0346eb3971943416699c3094cff087fb42c356019c3d91f8e8f55b9254c8caec48e9414af6817297d06725ffeb";
private const string _shake128 = "e5f88d0db79a71c39490beb9ebac21eaf4a5d6368438fca20f5e4ce77cfee9aa";
private const string _shake256 = "24d9e83198bbc7baf4dcd293bfc35ae3fff05399786c37318f1b1ef85f41970c66926f8a2a1f912d96e2d8e45535af88a301a1c200697437c1a65d7e980344bc";
#endif
private const string _spamsum = "3:hMCPQCE6AFQxWyENFACBE+rW6Tj7SMQmKozr9MVERkL:hZRdxZENFs+rPSromekL";
#if NET462_OR_GREATER || NETCOREAPP
private const string _xxhash32 = "8e331daa";
private const string _xxhash64 = "082bf6f0a49e1e18";
private const string _xxhash3 = "040474eb0eda9ff2";
private const string _xxhash128 = "d934b4b4a5e1e11baeef8012fbcd11e8";
#endif
#endregion
/// <summary>
/// Validate the hashes in a hash dictionary
/// </summary>
public static void ValidateHashes(Dictionary<HashType, string?>? hashDict)
{
Assert.NotNull(hashDict);
Assert.Equal(_adler32, hashDict![HashType.Adler32]);
#if NET7_0_OR_GREATER
Assert.Equal(_blake3, hashDict[HashType.BLAKE3]);
#endif
Assert.Equal(_crc16, hashDict[HashType.CRC16]);
Assert.Equal(_crc16_arc, hashDict[HashType.CRC16_ARC]);
Assert.Equal(_crc16_cdma2000, hashDict[HashType.CRC16_CDMA2000]);
Assert.Equal(_crc16_cms, hashDict[HashType.CRC16_CMS]);
Assert.Equal(_crc16_dds110, hashDict[HashType.CRC16_DDS110]);
Assert.Equal(_crc16_dectr, hashDict[HashType.CRC16_DECTR]);
Assert.Equal(_crc16_dectx, hashDict[HashType.CRC16_DECTX]);
Assert.Equal(_crc16_dnp, hashDict[HashType.CRC16_DNP]);
Assert.Equal(_crc16_en13757, hashDict[HashType.CRC16_EN13757]);
Assert.Equal(_crc16_genibus, hashDict[HashType.CRC16_GENIBUS]);
Assert.Equal(_crc16_gsm, hashDict[HashType.CRC16_GSM]);
Assert.Equal(_crc16_ibm3740, hashDict[HashType.CRC16_IBM3740]);
Assert.Equal(_crc16_ibmsdlc, hashDict[HashType.CRC16_IBMSDLC]);
//Assert.Equal(_crc16_isoiec144433a, hashDict[HashType.CRC16_ISOIEC144433A]);
Assert.Equal(_crc16_kermit, hashDict[HashType.CRC16_KERMIT]);
Assert.Equal(_crc16_lj1200, hashDict[HashType.CRC16_LJ1200]);
Assert.Equal(_crc16_m17, hashDict[HashType.CRC16_M17]);
Assert.Equal(_crc16_maximdow, hashDict[HashType.CRC16_MAXIMDOW]);
Assert.Equal(_crc16_mcrf4xx, hashDict[HashType.CRC16_MCRF4XX]);
Assert.Equal(_crc16_modbus, hashDict[HashType.CRC16_MODBUS]);
Assert.Equal(_crc16_nrsc5, hashDict[HashType.CRC16_NRSC5]);
Assert.Equal(_crc16_opensafetya, hashDict[HashType.CRC16_OPENSAFETYA]);
Assert.Equal(_crc16_opensafetyb, hashDict[HashType.CRC16_OPENSAFETYB]);
Assert.Equal(_crc16_profibus, hashDict[HashType.CRC16_PROFIBUS]);
//Assert.Equal(_crc16_riello, hashDict[HashType.CRC16_RIELLO]);
Assert.Equal(_crc16_spifujitsu, hashDict[HashType.CRC16_SPIFUJITSU]);
Assert.Equal(_crc16_t10dif, hashDict[HashType.CRC16_T10DIF]);
Assert.Equal(_crc16_teledisk, hashDict[HashType.CRC16_TELEDISK]);
//Assert.Equal(_crc16_tms37157, hashDict[HashType.CRC16_TMS37157]);
Assert.Equal(_crc16_umts, hashDict[HashType.CRC16_UMTS]);
Assert.Equal(_crc16_usb, hashDict[HashType.CRC16_USB]);
Assert.Equal(_crc16_xmodem, hashDict[HashType.CRC16_XMODEM]);
//Assert.Equal(_crc24_ble, hashDict[HashType.CRC24_BLE]);
Assert.Equal(_crc24_flexraya, hashDict[HashType.CRC24_FLEXRAYA]);
Assert.Equal(_crc24_flexrayb, hashDict[HashType.CRC24_FLEXRAYB]);
Assert.Equal(_crc24_interlaken, hashDict[HashType.CRC24_INTERLAKEN]);
Assert.Equal(_crc24_ltea, hashDict[HashType.CRC24_LTEA]);
Assert.Equal(_crc24_lteb, hashDict[HashType.CRC24_LTEB]);
Assert.Equal(_crc24_openpgp, hashDict[HashType.CRC24_OPENPGP]);
Assert.Equal(_crc24_os9, hashDict[HashType.CRC24_OS9]);
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
Assert.Equal(_crc32_aixm, hashDict[HashType.CRC32_AIXM]);
Assert.Equal(_crc32_autosar, hashDict[HashType.CRC32_AUTOSAR]);
Assert.Equal(_crc32_base91d, hashDict[HashType.CRC32_BASE91D]);
Assert.Equal(_crc32_bzip2, hashDict[HashType.CRC32_BZIP2]);
Assert.Equal(_crc32_cdromedc, hashDict[HashType.CRC32_CDROMEDC]);
Assert.Equal(_crc32_cksum, hashDict[HashType.CRC32_CKSUM]);
Assert.Equal(_crc32_iscsi, hashDict[HashType.CRC32_ISCSI]);
Assert.Equal(_crc32_isohdlc, hashDict[HashType.CRC32_ISOHDLC]);
Assert.Equal(_crc32_jamcrc, hashDict[HashType.CRC32_JAMCRC]);
Assert.Equal(_crc32_mef, hashDict[HashType.CRC32_MEF]);
Assert.Equal(_crc32_mpeg2, hashDict[HashType.CRC32_MPEG2]);
Assert.Equal(_crc32_xfer, hashDict[HashType.CRC32_XFER]);
Assert.Equal(_crc40_gsm, hashDict[HashType.CRC40_GSM]);
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
Assert.Equal(_crc64_ecma182, hashDict[HashType.CRC64_ECMA182]);
Assert.Equal(_crc64_goiso, hashDict[HashType.CRC64_GOISO]);
Assert.Equal(_crc64_ms, hashDict[HashType.CRC64_MS]);
Assert.Equal(_crc64_nvme, hashDict[HashType.CRC64_NVME]);
Assert.Equal(_crc64_redis, hashDict[HashType.CRC64_REDIS]);
Assert.Equal(_crc64_we, hashDict[HashType.CRC64_WE]);
Assert.Equal(_crc64_xz, hashDict[HashType.CRC64_XZ]);
Assert.Equal(_fletcher16, hashDict[HashType.Fletcher16]);
Assert.Equal(_fletcher32, hashDict[HashType.Fletcher32]);
Assert.Equal(_md5, hashDict[HashType.MD5]);
#if NETFRAMEWORK
Assert.Equal(_ripemd160, hashDict[HashType.RIPEMD160]);
#endif
Assert.Equal(_sha1, hashDict[HashType.SHA1]);
Assert.Equal(_sha256, hashDict[HashType.SHA256]);
Assert.Equal(_sha384, hashDict[HashType.SHA384]);
Assert.Equal(_sha512, hashDict[HashType.SHA512]);
#if NET8_0_OR_GREATER
if (System.Security.Cryptography.SHA3_256.IsSupported)
Assert.Equal(_sha3_256, hashDict[HashType.SHA3_256]);
if (System.Security.Cryptography.SHA3_384.IsSupported)
Assert.Equal(_sha3_384, hashDict[HashType.SHA3_384]);
if (System.Security.Cryptography.SHA3_512.IsSupported)
Assert.Equal(_sha3_512, hashDict[HashType.SHA3_512]);
if (System.Security.Cryptography.Shake128.IsSupported)
Assert.Equal(_shake128, hashDict[HashType.SHAKE128]);
if (System.Security.Cryptography.Shake256.IsSupported)
Assert.Equal(_shake256, hashDict[HashType.SHAKE256]);
#endif
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
#if NET462_OR_GREATER || NETCOREAPP
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
#endif
}
}
}

View File

@@ -52,6 +52,7 @@ using Aaru.Helpers;
#if NETCOREAPP3_1_OR_GREATER
using Ssse3 = System.Runtime.Intrinsics.X86.Ssse3;
#endif
using static Aaru.Helpers.Extensions;
namespace Aaru.Checksums;
@@ -359,12 +360,12 @@ public sealed class Adler32Context : IChecksum
ushort localSum2 = 0;
var buffer = new byte[65536];
int read = fileStream.EnsureRead(buffer, 0, 65536);
int read = EnsureRead(fileStream, buffer, 0, 65536);
while(read > 0)
{
Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
read = fileStream.EnsureRead(buffer, 0, 65536);
read = EnsureRead(fileStream, buffer, 0, 65536);
}
var finalSum = (uint)(localSum2 << 16 | localSum1);

View File

@@ -1,274 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : CRC16CCITTContext.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Implements a CRC16 algorithm with the CCITT polynomial.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
namespace Aaru.Checksums;
/// <inheritdoc />
/// <summary>Implements the CRC16 algorithm with CCITT polynomial and seed</summary>
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
public sealed class CRC16CcittContext : Crc16Context
{
/// <summary>CCITT CRC16 polynomial</summary>
public const ushort CRC16_CCITT_POLY = 0x8408;
/// <summary>CCITT CRC16 seed</summary>
public const ushort CRC16_CCITT_SEED = 0x0000;
static readonly ushort[][] _ccittCrc16Table =
{
new ushort[]
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C,
0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318,
0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4,
0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630,
0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4,
0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969,
0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF,
0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13,
0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9,
0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046,
0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2,
0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2,
0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E,
0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E,
0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1,
0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9,
0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
},
new ushort[]
{
0x0000, 0x3331, 0x6662, 0x5553, 0xCCC4, 0xFFF5, 0xAAA6, 0x9997, 0x89A9, 0xBA98, 0xEFCB, 0xDCFA, 0x456D,
0x765C, 0x230F, 0x103E, 0x0373, 0x3042, 0x6511, 0x5620, 0xCFB7, 0xFC86, 0xA9D5, 0x9AE4, 0x8ADA, 0xB9EB,
0xECB8, 0xDF89, 0x461E, 0x752F, 0x207C, 0x134D, 0x06E6, 0x35D7, 0x6084, 0x53B5, 0xCA22, 0xF913, 0xAC40,
0x9F71, 0x8F4F, 0xBC7E, 0xE92D, 0xDA1C, 0x438B, 0x70BA, 0x25E9, 0x16D8, 0x0595, 0x36A4, 0x63F7, 0x50C6,
0xC951, 0xFA60, 0xAF33, 0x9C02, 0x8C3C, 0xBF0D, 0xEA5E, 0xD96F, 0x40F8, 0x73C9, 0x269A, 0x15AB, 0x0DCC,
0x3EFD, 0x6BAE, 0x589F, 0xC108, 0xF239, 0xA76A, 0x945B, 0x8465, 0xB754, 0xE207, 0xD136, 0x48A1, 0x7B90,
0x2EC3, 0x1DF2, 0x0EBF, 0x3D8E, 0x68DD, 0x5BEC, 0xC27B, 0xF14A, 0xA419, 0x9728, 0x8716, 0xB427, 0xE174,
0xD245, 0x4BD2, 0x78E3, 0x2DB0, 0x1E81, 0x0B2A, 0x381B, 0x6D48, 0x5E79, 0xC7EE, 0xF4DF, 0xA18C, 0x92BD,
0x8283, 0xB1B2, 0xE4E1, 0xD7D0, 0x4E47, 0x7D76, 0x2825, 0x1B14, 0x0859, 0x3B68, 0x6E3B, 0x5D0A, 0xC49D,
0xF7AC, 0xA2FF, 0x91CE, 0x81F0, 0xB2C1, 0xE792, 0xD4A3, 0x4D34, 0x7E05, 0x2B56, 0x1867, 0x1B98, 0x28A9,
0x7DFA, 0x4ECB, 0xD75C, 0xE46D, 0xB13E, 0x820F, 0x9231, 0xA100, 0xF453, 0xC762, 0x5EF5, 0x6DC4, 0x3897,
0x0BA6, 0x18EB, 0x2BDA, 0x7E89, 0x4DB8, 0xD42F, 0xE71E, 0xB24D, 0x817C, 0x9142, 0xA273, 0xF720, 0xC411,
0x5D86, 0x6EB7, 0x3BE4, 0x08D5, 0x1D7E, 0x2E4F, 0x7B1C, 0x482D, 0xD1BA, 0xE28B, 0xB7D8, 0x84E9, 0x94D7,
0xA7E6, 0xF2B5, 0xC184, 0x5813, 0x6B22, 0x3E71, 0x0D40, 0x1E0D, 0x2D3C, 0x786F, 0x4B5E, 0xD2C9, 0xE1F8,
0xB4AB, 0x879A, 0x97A4, 0xA495, 0xF1C6, 0xC2F7, 0x5B60, 0x6851, 0x3D02, 0x0E33, 0x1654, 0x2565, 0x7036,
0x4307, 0xDA90, 0xE9A1, 0xBCF2, 0x8FC3, 0x9FFD, 0xACCC, 0xF99F, 0xCAAE, 0x5339, 0x6008, 0x355B, 0x066A,
0x1527, 0x2616, 0x7345, 0x4074, 0xD9E3, 0xEAD2, 0xBF81, 0x8CB0, 0x9C8E, 0xAFBF, 0xFAEC, 0xC9DD, 0x504A,
0x637B, 0x3628, 0x0519, 0x10B2, 0x2383, 0x76D0, 0x45E1, 0xDC76, 0xEF47, 0xBA14, 0x8925, 0x991B, 0xAA2A,
0xFF79, 0xCC48, 0x55DF, 0x66EE, 0x33BD, 0x008C, 0x13C1, 0x20F0, 0x75A3, 0x4692, 0xDF05, 0xEC34, 0xB967,
0x8A56, 0x9A68, 0xA959, 0xFC0A, 0xCF3B, 0x56AC, 0x659D, 0x30CE, 0x03FF
},
new ushort[]
{
0x0000, 0x3730, 0x6E60, 0x5950, 0xDCC0, 0xEBF0, 0xB2A0, 0x8590, 0xA9A1, 0x9E91, 0xC7C1, 0xF0F1, 0x7561,
0x4251, 0x1B01, 0x2C31, 0x4363, 0x7453, 0x2D03, 0x1A33, 0x9FA3, 0xA893, 0xF1C3, 0xC6F3, 0xEAC2, 0xDDF2,
0x84A2, 0xB392, 0x3602, 0x0132, 0x5862, 0x6F52, 0x86C6, 0xB1F6, 0xE8A6, 0xDF96, 0x5A06, 0x6D36, 0x3466,
0x0356, 0x2F67, 0x1857, 0x4107, 0x7637, 0xF3A7, 0xC497, 0x9DC7, 0xAAF7, 0xC5A5, 0xF295, 0xABC5, 0x9CF5,
0x1965, 0x2E55, 0x7705, 0x4035, 0x6C04, 0x5B34, 0x0264, 0x3554, 0xB0C4, 0x87F4, 0xDEA4, 0xE994, 0x1DAD,
0x2A9D, 0x73CD, 0x44FD, 0xC16D, 0xF65D, 0xAF0D, 0x983D, 0xB40C, 0x833C, 0xDA6C, 0xED5C, 0x68CC, 0x5FFC,
0x06AC, 0x319C, 0x5ECE, 0x69FE, 0x30AE, 0x079E, 0x820E, 0xB53E, 0xEC6E, 0xDB5E, 0xF76F, 0xC05F, 0x990F,
0xAE3F, 0x2BAF, 0x1C9F, 0x45CF, 0x72FF, 0x9B6B, 0xAC5B, 0xF50B, 0xC23B, 0x47AB, 0x709B, 0x29CB, 0x1EFB,
0x32CA, 0x05FA, 0x5CAA, 0x6B9A, 0xEE0A, 0xD93A, 0x806A, 0xB75A, 0xD808, 0xEF38, 0xB668, 0x8158, 0x04C8,
0x33F8, 0x6AA8, 0x5D98, 0x71A9, 0x4699, 0x1FC9, 0x28F9, 0xAD69, 0x9A59, 0xC309, 0xF439, 0x3B5A, 0x0C6A,
0x553A, 0x620A, 0xE79A, 0xD0AA, 0x89FA, 0xBECA, 0x92FB, 0xA5CB, 0xFC9B, 0xCBAB, 0x4E3B, 0x790B, 0x205B,
0x176B, 0x7839, 0x4F09, 0x1659, 0x2169, 0xA4F9, 0x93C9, 0xCA99, 0xFDA9, 0xD198, 0xE6A8, 0xBFF8, 0x88C8,
0x0D58, 0x3A68, 0x6338, 0x5408, 0xBD9C, 0x8AAC, 0xD3FC, 0xE4CC, 0x615C, 0x566C, 0x0F3C, 0x380C, 0x143D,
0x230D, 0x7A5D, 0x4D6D, 0xC8FD, 0xFFCD, 0xA69D, 0x91AD, 0xFEFF, 0xC9CF, 0x909F, 0xA7AF, 0x223F, 0x150F,
0x4C5F, 0x7B6F, 0x575E, 0x606E, 0x393E, 0x0E0E, 0x8B9E, 0xBCAE, 0xE5FE, 0xD2CE, 0x26F7, 0x11C7, 0x4897,
0x7FA7, 0xFA37, 0xCD07, 0x9457, 0xA367, 0x8F56, 0xB866, 0xE136, 0xD606, 0x5396, 0x64A6, 0x3DF6, 0x0AC6,
0x6594, 0x52A4, 0x0BF4, 0x3CC4, 0xB954, 0x8E64, 0xD734, 0xE004, 0xCC35, 0xFB05, 0xA255, 0x9565, 0x10F5,
0x27C5, 0x7E95, 0x49A5, 0xA031, 0x9701, 0xCE51, 0xF961, 0x7CF1, 0x4BC1, 0x1291, 0x25A1, 0x0990, 0x3EA0,
0x67F0, 0x50C0, 0xD550, 0xE260, 0xBB30, 0x8C00, 0xE352, 0xD462, 0x8D32, 0xBA02, 0x3F92, 0x08A2, 0x51F2,
0x66C2, 0x4AF3, 0x7DC3, 0x2493, 0x13A3, 0x9633, 0xA103, 0xF853, 0xCF63
},
new ushort[]
{
0x0000, 0x76B4, 0xED68, 0x9BDC, 0xCAF1, 0xBC45, 0x2799, 0x512D, 0x85C3, 0xF377, 0x68AB, 0x1E1F, 0x4F32,
0x3986, 0xA25A, 0xD4EE, 0x1BA7, 0x6D13, 0xF6CF, 0x807B, 0xD156, 0xA7E2, 0x3C3E, 0x4A8A, 0x9E64, 0xE8D0,
0x730C, 0x05B8, 0x5495, 0x2221, 0xB9FD, 0xCF49, 0x374E, 0x41FA, 0xDA26, 0xAC92, 0xFDBF, 0x8B0B, 0x10D7,
0x6663, 0xB28D, 0xC439, 0x5FE5, 0x2951, 0x787C, 0x0EC8, 0x9514, 0xE3A0, 0x2CE9, 0x5A5D, 0xC181, 0xB735,
0xE618, 0x90AC, 0x0B70, 0x7DC4, 0xA92A, 0xDF9E, 0x4442, 0x32F6, 0x63DB, 0x156F, 0x8EB3, 0xF807, 0x6E9C,
0x1828, 0x83F4, 0xF540, 0xA46D, 0xD2D9, 0x4905, 0x3FB1, 0xEB5F, 0x9DEB, 0x0637, 0x7083, 0x21AE, 0x571A,
0xCCC6, 0xBA72, 0x753B, 0x038F, 0x9853, 0xEEE7, 0xBFCA, 0xC97E, 0x52A2, 0x2416, 0xF0F8, 0x864C, 0x1D90,
0x6B24, 0x3A09, 0x4CBD, 0xD761, 0xA1D5, 0x59D2, 0x2F66, 0xB4BA, 0xC20E, 0x9323, 0xE597, 0x7E4B, 0x08FF,
0xDC11, 0xAAA5, 0x3179, 0x47CD, 0x16E0, 0x6054, 0xFB88, 0x8D3C, 0x4275, 0x34C1, 0xAF1D, 0xD9A9, 0x8884,
0xFE30, 0x65EC, 0x1358, 0xC7B6, 0xB102, 0x2ADE, 0x5C6A, 0x0D47, 0x7BF3, 0xE02F, 0x969B, 0xDD38, 0xAB8C,
0x3050, 0x46E4, 0x17C9, 0x617D, 0xFAA1, 0x8C15, 0x58FB, 0x2E4F, 0xB593, 0xC327, 0x920A, 0xE4BE, 0x7F62,
0x09D6, 0xC69F, 0xB02B, 0x2BF7, 0x5D43, 0x0C6E, 0x7ADA, 0xE106, 0x97B2, 0x435C, 0x35E8, 0xAE34, 0xD880,
0x89AD, 0xFF19, 0x64C5, 0x1271, 0xEA76, 0x9CC2, 0x071E, 0x71AA, 0x2087, 0x5633, 0xCDEF, 0xBB5B, 0x6FB5,
0x1901, 0x82DD, 0xF469, 0xA544, 0xD3F0, 0x482C, 0x3E98, 0xF1D1, 0x8765, 0x1CB9, 0x6A0D, 0x3B20, 0x4D94,
0xD648, 0xA0FC, 0x7412, 0x02A6, 0x997A, 0xEFCE, 0xBEE3, 0xC857, 0x538B, 0x253F, 0xB3A4, 0xC510, 0x5ECC,
0x2878, 0x7955, 0x0FE1, 0x943D, 0xE289, 0x3667, 0x40D3, 0xDB0F, 0xADBB, 0xFC96, 0x8A22, 0x11FE, 0x674A,
0xA803, 0xDEB7, 0x456B, 0x33DF, 0x62F2, 0x1446, 0x8F9A, 0xF92E, 0x2DC0, 0x5B74, 0xC0A8, 0xB61C, 0xE731,
0x9185, 0x0A59, 0x7CED, 0x84EA, 0xF25E, 0x6982, 0x1F36, 0x4E1B, 0x38AF, 0xA373, 0xD5C7, 0x0129, 0x779D,
0xEC41, 0x9AF5, 0xCBD8, 0xBD6C, 0x26B0, 0x5004, 0x9F4D, 0xE9F9, 0x7225, 0x0491, 0x55BC, 0x2308, 0xB8D4,
0xCE60, 0x1A8E, 0x6C3A, 0xF7E6, 0x8152, 0xD07F, 0xA6CB, 0x3D17, 0x4BA3
},
new ushort[]
{
0x0000, 0xAA51, 0x4483, 0xEED2, 0x8906, 0x2357, 0xCD85, 0x67D4, 0x022D, 0xA87C, 0x46AE, 0xECFF, 0x8B2B,
0x217A, 0xCFA8, 0x65F9, 0x045A, 0xAE0B, 0x40D9, 0xEA88, 0x8D5C, 0x270D, 0xC9DF, 0x638E, 0x0677, 0xAC26,
0x42F4, 0xE8A5, 0x8F71, 0x2520, 0xCBF2, 0x61A3, 0x08B4, 0xA2E5, 0x4C37, 0xE666, 0x81B2, 0x2BE3, 0xC531,
0x6F60, 0x0A99, 0xA0C8, 0x4E1A, 0xE44B, 0x839F, 0x29CE, 0xC71C, 0x6D4D, 0x0CEE, 0xA6BF, 0x486D, 0xE23C,
0x85E8, 0x2FB9, 0xC16B, 0x6B3A, 0x0EC3, 0xA492, 0x4A40, 0xE011, 0x87C5, 0x2D94, 0xC346, 0x6917, 0x1168,
0xBB39, 0x55EB, 0xFFBA, 0x986E, 0x323F, 0xDCED, 0x76BC, 0x1345, 0xB914, 0x57C6, 0xFD97, 0x9A43, 0x3012,
0xDEC0, 0x7491, 0x1532, 0xBF63, 0x51B1, 0xFBE0, 0x9C34, 0x3665, 0xD8B7, 0x72E6, 0x171F, 0xBD4E, 0x539C,
0xF9CD, 0x9E19, 0x3448, 0xDA9A, 0x70CB, 0x19DC, 0xB38D, 0x5D5F, 0xF70E, 0x90DA, 0x3A8B, 0xD459, 0x7E08,
0x1BF1, 0xB1A0, 0x5F72, 0xF523, 0x92F7, 0x38A6, 0xD674, 0x7C25, 0x1D86, 0xB7D7, 0x5905, 0xF354, 0x9480,
0x3ED1, 0xD003, 0x7A52, 0x1FAB, 0xB5FA, 0x5B28, 0xF179, 0x96AD, 0x3CFC, 0xD22E, 0x787F, 0x22D0, 0x8881,
0x6653, 0xCC02, 0xABD6, 0x0187, 0xEF55, 0x4504, 0x20FD, 0x8AAC, 0x647E, 0xCE2F, 0xA9FB, 0x03AA, 0xED78,
0x4729, 0x268A, 0x8CDB, 0x6209, 0xC858, 0xAF8C, 0x05DD, 0xEB0F, 0x415E, 0x24A7, 0x8EF6, 0x6024, 0xCA75,
0xADA1, 0x07F0, 0xE922, 0x4373, 0x2A64, 0x8035, 0x6EE7, 0xC4B6, 0xA362, 0x0933, 0xE7E1, 0x4DB0, 0x2849,
0x8218, 0x6CCA, 0xC69B, 0xA14F, 0x0B1E, 0xE5CC, 0x4F9D, 0x2E3E, 0x846F, 0x6ABD, 0xC0EC, 0xA738, 0x0D69,
0xE3BB, 0x49EA, 0x2C13, 0x8642, 0x6890, 0xC2C1, 0xA515, 0x0F44, 0xE196, 0x4BC7, 0x33B8, 0x99E9, 0x773B,
0xDD6A, 0xBABE, 0x10EF, 0xFE3D, 0x546C, 0x3195, 0x9BC4, 0x7516, 0xDF47, 0xB893, 0x12C2, 0xFC10, 0x5641,
0x37E2, 0x9DB3, 0x7361, 0xD930, 0xBEE4, 0x14B5, 0xFA67, 0x5036, 0x35CF, 0x9F9E, 0x714C, 0xDB1D, 0xBCC9,
0x1698, 0xF84A, 0x521B, 0x3B0C, 0x915D, 0x7F8F, 0xD5DE, 0xB20A, 0x185B, 0xF689, 0x5CD8, 0x3921, 0x9370,
0x7DA2, 0xD7F3, 0xB027, 0x1A76, 0xF4A4, 0x5EF5, 0x3F56, 0x9507, 0x7BD5, 0xD184, 0xB650, 0x1C01, 0xF2D3,
0x5882, 0x3D7B, 0x972A, 0x79F8, 0xD3A9, 0xB47D, 0x1E2C, 0xF0FE, 0x5AAF
},
new ushort[]
{
0x0000, 0x45A0, 0x8B40, 0xCEE0, 0x06A1, 0x4301, 0x8DE1, 0xC841, 0x0D42, 0x48E2, 0x8602, 0xC3A2, 0x0BE3,
0x4E43, 0x80A3, 0xC503, 0x1A84, 0x5F24, 0x91C4, 0xD464, 0x1C25, 0x5985, 0x9765, 0xD2C5, 0x17C6, 0x5266,
0x9C86, 0xD926, 0x1167, 0x54C7, 0x9A27, 0xDF87, 0x3508, 0x70A8, 0xBE48, 0xFBE8, 0x33A9, 0x7609, 0xB8E9,
0xFD49, 0x384A, 0x7DEA, 0xB30A, 0xF6AA, 0x3EEB, 0x7B4B, 0xB5AB, 0xF00B, 0x2F8C, 0x6A2C, 0xA4CC, 0xE16C,
0x292D, 0x6C8D, 0xA26D, 0xE7CD, 0x22CE, 0x676E, 0xA98E, 0xEC2E, 0x246F, 0x61CF, 0xAF2F, 0xEA8F, 0x6A10,
0x2FB0, 0xE150, 0xA4F0, 0x6CB1, 0x2911, 0xE7F1, 0xA251, 0x6752, 0x22F2, 0xEC12, 0xA9B2, 0x61F3, 0x2453,
0xEAB3, 0xAF13, 0x7094, 0x3534, 0xFBD4, 0xBE74, 0x7635, 0x3395, 0xFD75, 0xB8D5, 0x7DD6, 0x3876, 0xF696,
0xB336, 0x7B77, 0x3ED7, 0xF037, 0xB597, 0x5F18, 0x1AB8, 0xD458, 0x91F8, 0x59B9, 0x1C19, 0xD2F9, 0x9759,
0x525A, 0x17FA, 0xD91A, 0x9CBA, 0x54FB, 0x115B, 0xDFBB, 0x9A1B, 0x459C, 0x003C, 0xCEDC, 0x8B7C, 0x433D,
0x069D, 0xC87D, 0x8DDD, 0x48DE, 0x0D7E, 0xC39E, 0x863E, 0x4E7F, 0x0BDF, 0xC53F, 0x809F, 0xD420, 0x9180,
0x5F60, 0x1AC0, 0xD281, 0x9721, 0x59C1, 0x1C61, 0xD962, 0x9CC2, 0x5222, 0x1782, 0xDFC3, 0x9A63, 0x5483,
0x1123, 0xCEA4, 0x8B04, 0x45E4, 0x0044, 0xC805, 0x8DA5, 0x4345, 0x06E5, 0xC3E6, 0x8646, 0x48A6, 0x0D06,
0xC547, 0x80E7, 0x4E07, 0x0BA7, 0xE128, 0xA488, 0x6A68, 0x2FC8, 0xE789, 0xA229, 0x6CC9, 0x2969, 0xEC6A,
0xA9CA, 0x672A, 0x228A, 0xEACB, 0xAF6B, 0x618B, 0x242B, 0xFBAC, 0xBE0C, 0x70EC, 0x354C, 0xFD0D, 0xB8AD,
0x764D, 0x33ED, 0xF6EE, 0xB34E, 0x7DAE, 0x380E, 0xF04F, 0xB5EF, 0x7B0F, 0x3EAF, 0xBE30, 0xFB90, 0x3570,
0x70D0, 0xB891, 0xFD31, 0x33D1, 0x7671, 0xB372, 0xF6D2, 0x3832, 0x7D92, 0xB5D3, 0xF073, 0x3E93, 0x7B33,
0xA4B4, 0xE114, 0x2FF4, 0x6A54, 0xA215, 0xE7B5, 0x2955, 0x6CF5, 0xA9F6, 0xEC56, 0x22B6, 0x6716, 0xAF57,
0xEAF7, 0x2417, 0x61B7, 0x8B38, 0xCE98, 0x0078, 0x45D8, 0x8D99, 0xC839, 0x06D9, 0x4379, 0x867A, 0xC3DA,
0x0D3A, 0x489A, 0x80DB, 0xC57B, 0x0B9B, 0x4E3B, 0x91BC, 0xD41C, 0x1AFC, 0x5F5C, 0x971D, 0xD2BD, 0x1C5D,
0x59FD, 0x9CFE, 0xD95E, 0x17BE, 0x521E, 0x9A5F, 0xDFFF, 0x111F, 0x54BF
},
new ushort[]
{
0x0000, 0xB861, 0x60E3, 0xD882, 0xC1C6, 0x79A7, 0xA125, 0x1944, 0x93AD, 0x2BCC, 0xF34E, 0x4B2F, 0x526B,
0xEA0A, 0x3288, 0x8AE9, 0x377B, 0x8F1A, 0x5798, 0xEFF9, 0xF6BD, 0x4EDC, 0x965E, 0x2E3F, 0xA4D6, 0x1CB7,
0xC435, 0x7C54, 0x6510, 0xDD71, 0x05F3, 0xBD92, 0x6EF6, 0xD697, 0x0E15, 0xB674, 0xAF30, 0x1751, 0xCFD3,
0x77B2, 0xFD5B, 0x453A, 0x9DB8, 0x25D9, 0x3C9D, 0x84FC, 0x5C7E, 0xE41F, 0x598D, 0xE1EC, 0x396E, 0x810F,
0x984B, 0x202A, 0xF8A8, 0x40C9, 0xCA20, 0x7241, 0xAAC3, 0x12A2, 0x0BE6, 0xB387, 0x6B05, 0xD364, 0xDDEC,
0x658D, 0xBD0F, 0x056E, 0x1C2A, 0xA44B, 0x7CC9, 0xC4A8, 0x4E41, 0xF620, 0x2EA2, 0x96C3, 0x8F87, 0x37E6,
0xEF64, 0x5705, 0xEA97, 0x52F6, 0x8A74, 0x3215, 0x2B51, 0x9330, 0x4BB2, 0xF3D3, 0x793A, 0xC15B, 0x19D9,
0xA1B8, 0xB8FC, 0x009D, 0xD81F, 0x607E, 0xB31A, 0x0B7B, 0xD3F9, 0x6B98, 0x72DC, 0xCABD, 0x123F, 0xAA5E,
0x20B7, 0x98D6, 0x4054, 0xF835, 0xE171, 0x5910, 0x8192, 0x39F3, 0x8461, 0x3C00, 0xE482, 0x5CE3, 0x45A7,
0xFDC6, 0x2544, 0x9D25, 0x17CC, 0xAFAD, 0x772F, 0xCF4E, 0xD60A, 0x6E6B, 0xB6E9, 0x0E88, 0xABF9, 0x1398,
0xCB1A, 0x737B, 0x6A3F, 0xD25E, 0x0ADC, 0xB2BD, 0x3854, 0x8035, 0x58B7, 0xE0D6, 0xF992, 0x41F3, 0x9971,
0x2110, 0x9C82, 0x24E3, 0xFC61, 0x4400, 0x5D44, 0xE525, 0x3DA7, 0x85C6, 0x0F2F, 0xB74E, 0x6FCC, 0xD7AD,
0xCEE9, 0x7688, 0xAE0A, 0x166B, 0xC50F, 0x7D6E, 0xA5EC, 0x1D8D, 0x04C9, 0xBCA8, 0x642A, 0xDC4B, 0x56A2,
0xEEC3, 0x3641, 0x8E20, 0x9764, 0x2F05, 0xF787, 0x4FE6, 0xF274, 0x4A15, 0x9297, 0x2AF6, 0x33B2, 0x8BD3,
0x5351, 0xEB30, 0x61D9, 0xD9B8, 0x013A, 0xB95B, 0xA01F, 0x187E, 0xC0FC, 0x789D, 0x7615, 0xCE74, 0x16F6,
0xAE97, 0xB7D3, 0x0FB2, 0xD730, 0x6F51, 0xE5B8, 0x5DD9, 0x855B, 0x3D3A, 0x247E, 0x9C1F, 0x449D, 0xFCFC,
0x416E, 0xF90F, 0x218D, 0x99EC, 0x80A8, 0x38C9, 0xE04B, 0x582A, 0xD2C3, 0x6AA2, 0xB220, 0x0A41, 0x1305,
0xAB64, 0x73E6, 0xCB87, 0x18E3, 0xA082, 0x7800, 0xC061, 0xD925, 0x6144, 0xB9C6, 0x01A7, 0x8B4E, 0x332F,
0xEBAD, 0x53CC, 0x4A88, 0xF2E9, 0x2A6B, 0x920A, 0x2F98, 0x97F9, 0x4F7B, 0xF71A, 0xEE5E, 0x563F, 0x8EBD,
0x36DC, 0xBC35, 0x0454, 0xDCD6, 0x64B7, 0x7DF3, 0xC592, 0x1D10, 0xA571
},
new ushort[]
{
0x0000, 0x47D3, 0x8FA6, 0xC875, 0x0F6D, 0x48BE, 0x80CB, 0xC718, 0x1EDA, 0x5909, 0x917C, 0xD6AF, 0x11B7,
0x5664, 0x9E11, 0xD9C2, 0x3DB4, 0x7A67, 0xB212, 0xF5C1, 0x32D9, 0x750A, 0xBD7F, 0xFAAC, 0x236E, 0x64BD,
0xACC8, 0xEB1B, 0x2C03, 0x6BD0, 0xA3A5, 0xE476, 0x7B68, 0x3CBB, 0xF4CE, 0xB31D, 0x7405, 0x33D6, 0xFBA3,
0xBC70, 0x65B2, 0x2261, 0xEA14, 0xADC7, 0x6ADF, 0x2D0C, 0xE579, 0xA2AA, 0x46DC, 0x010F, 0xC97A, 0x8EA9,
0x49B1, 0x0E62, 0xC617, 0x81C4, 0x5806, 0x1FD5, 0xD7A0, 0x9073, 0x576B, 0x10B8, 0xD8CD, 0x9F1E, 0xF6D0,
0xB103, 0x7976, 0x3EA5, 0xF9BD, 0xBE6E, 0x761B, 0x31C8, 0xE80A, 0xAFD9, 0x67AC, 0x207F, 0xE767, 0xA0B4,
0x68C1, 0x2F12, 0xCB64, 0x8CB7, 0x44C2, 0x0311, 0xC409, 0x83DA, 0x4BAF, 0x0C7C, 0xD5BE, 0x926D, 0x5A18,
0x1DCB, 0xDAD3, 0x9D00, 0x5575, 0x12A6, 0x8DB8, 0xCA6B, 0x021E, 0x45CD, 0x82D5, 0xC506, 0x0D73, 0x4AA0,
0x9362, 0xD4B1, 0x1CC4, 0x5B17, 0x9C0F, 0xDBDC, 0x13A9, 0x547A, 0xB00C, 0xF7DF, 0x3FAA, 0x7879, 0xBF61,
0xF8B2, 0x30C7, 0x7714, 0xAED6, 0xE905, 0x2170, 0x66A3, 0xA1BB, 0xE668, 0x2E1D, 0x69CE, 0xFD81, 0xBA52,
0x7227, 0x35F4, 0xF2EC, 0xB53F, 0x7D4A, 0x3A99, 0xE35B, 0xA488, 0x6CFD, 0x2B2E, 0xEC36, 0xABE5, 0x6390,
0x2443, 0xC035, 0x87E6, 0x4F93, 0x0840, 0xCF58, 0x888B, 0x40FE, 0x072D, 0xDEEF, 0x993C, 0x5149, 0x169A,
0xD182, 0x9651, 0x5E24, 0x19F7, 0x86E9, 0xC13A, 0x094F, 0x4E9C, 0x8984, 0xCE57, 0x0622, 0x41F1, 0x9833,
0xDFE0, 0x1795, 0x5046, 0x975E, 0xD08D, 0x18F8, 0x5F2B, 0xBB5D, 0xFC8E, 0x34FB, 0x7328, 0xB430, 0xF3E3,
0x3B96, 0x7C45, 0xA587, 0xE254, 0x2A21, 0x6DF2, 0xAAEA, 0xED39, 0x254C, 0x629F, 0x0B51, 0x4C82, 0x84F7,
0xC324, 0x043C, 0x43EF, 0x8B9A, 0xCC49, 0x158B, 0x5258, 0x9A2D, 0xDDFE, 0x1AE6, 0x5D35, 0x9540, 0xD293,
0x36E5, 0x7136, 0xB943, 0xFE90, 0x3988, 0x7E5B, 0xB62E, 0xF1FD, 0x283F, 0x6FEC, 0xA799, 0xE04A, 0x2752,
0x6081, 0xA8F4, 0xEF27, 0x7039, 0x37EA, 0xFF9F, 0xB84C, 0x7F54, 0x3887, 0xF0F2, 0xB721, 0x6EE3, 0x2930,
0xE145, 0xA696, 0x618E, 0x265D, 0xEE28, 0xA9FB, 0x4D8D, 0x0A5E, 0xC22B, 0x85F8, 0x42E0, 0x0533, 0xCD46,
0x8A95, 0x5357, 0x1484, 0xDCF1, 0x9B22, 0x5C3A, 0x1BE9, 0xD39C, 0x944F
}
};
/// <summary>Initializes an instance of the CRC16 with CCITT polynomial and seed.</summary>
/// <inheritdoc />
public CRC16CcittContext() : base(CRC16_CCITT_POLY, CRC16_CCITT_SEED, _ccittCrc16Table, true) {}
public new string Name => "CRC-16 (CCITT)";
public new Guid Id => new("4C3BD0D5-24BD-4D45-BC19-A90A5AA5CC9D");
public new string Author => "Natalia Portillo";
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
public static byte[] File(string filename)
{
File(filename, out byte[] hash);
return hash;
}
/// <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) =>
File(filename, out hash, CRC16_CCITT_POLY, CRC16_CCITT_SEED, _ccittCrc16Table, true);
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of the data buffer to hash.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, uint len, out byte[] hash) =>
Data(data, len, out hash, CRC16_CCITT_POLY, CRC16_CCITT_SEED, _ccittCrc16Table, true);
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
/// <summary>Calculates the CCITT CRC16 of the specified buffer with the specified parameters</summary>
/// <param name="buffer">Buffer</param>
public static ushort Calculate(byte[] buffer) =>
Calculate(buffer, CRC16_CCITT_POLY, CRC16_CCITT_SEED, _ccittCrc16Table, true);
}

View File

@@ -1,649 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : CRC16Context.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Implements a CRC16 algorithm.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using Aaru.CommonTypes.Interfaces;
using Aaru.Helpers;
namespace Aaru.Checksums;
/// <inheritdoc />
/// <summary>Implements a CRC16 algorithm</summary>
public class Crc16Context : IChecksum
{
readonly ushort _finalSeed;
readonly bool _inverse;
readonly IntPtr _nativeContext;
readonly ushort[][]? _table;
readonly bool _useCcitt;
readonly bool _useIbm;
readonly bool _useNative;
ushort _hashInt;
/// <summary>Initializes the CRC16 table with a custom polynomial and seed</summary>
public Crc16Context(ushort polynomial, ushort seed, ushort[][] table, bool inverse)
{
_hashInt = seed;
_finalSeed = seed;
_inverse = inverse;
_useNative = Native.IsSupported;
_useCcitt = polynomial == CRC16CcittContext.CRC16_CCITT_POLY &&
seed == CRC16CcittContext.CRC16_CCITT_SEED &&
inverse;
_useIbm = polynomial == CRC16IbmContext.CRC16_IBM_POLY && seed == CRC16IbmContext.CRC16_IBM_SEED && !inverse;
if(_useCcitt && _useNative)
{
_nativeContext = crc16_ccitt_init();
_useNative = _nativeContext != IntPtr.Zero;
}
else if(_useIbm && _useNative)
{
_nativeContext = crc16_init();
_useNative = _nativeContext != IntPtr.Zero;
}
else
_useNative = false;
if(!_useNative)
_table = table ?? GenerateTable(polynomial, inverse);
}
#region IChecksum Members
/// <inheritdoc />
public string Name => "CRC-16";
/// <inheritdoc />
public Guid Id => new("D69CF1E7-4A7B-4605-9291-3A1BE4C2951F");
/// <inheritdoc />
public string Author => "Natalia Portillo";
/// <inheritdoc />
/// <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)
{
switch(_useNative)
{
case true when _useCcitt:
crc16_ccitt_update(_nativeContext, data, len);
break;
case true when _useIbm:
crc16_update(_nativeContext, data, len);
break;
default:
{
if(_inverse)
StepInverse(ref _hashInt, _table!, data, len);
else
Step(ref _hashInt, _table!, data, len);
break;
}
}
}
/// <inheritdoc />
/// <summary>Updates the hash with data.</summary>
/// <param name="data">Data buffer.</param>
public void Update(byte[] data) => Update(data, (uint)data.Length);
/// <inheritdoc />
/// <summary>Returns a byte array of the hash value.</summary>
public byte[] Final()
{
ushort crc = 0;
switch(_useNative)
{
case true when _useCcitt:
crc16_ccitt_final(_nativeContext, ref crc);
crc16_ccitt_free(_nativeContext);
break;
case true when _useIbm:
crc16_final(_nativeContext, ref crc);
crc16_free(_nativeContext);
break;
default:
{
if(_inverse)
crc = (ushort)~(_hashInt ^ _finalSeed);
else
crc = (ushort)(_hashInt ^ _finalSeed);
break;
}
}
return BigEndianBitConverter.GetBytes(crc);
}
/// <inheritdoc />
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
public string End()
{
var crc16Output = new StringBuilder();
ushort final = 0;
switch(_useNative)
{
case true when _useCcitt:
crc16_ccitt_final(_nativeContext, ref final);
crc16_ccitt_free(_nativeContext);
break;
case true when _useIbm:
crc16_final(_nativeContext, ref final);
crc16_free(_nativeContext);
break;
default:
{
if(_inverse)
final = (ushort)~(_hashInt ^ _finalSeed);
else
final = (ushort)(_hashInt ^ _finalSeed);
break;
}
}
byte[] finalBytes = BigEndianBitConverter.GetBytes(final);
foreach(byte t in finalBytes)
crc16Output.Append(t.ToString("x2"));
return crc16Output.ToString();
}
#endregion
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern IntPtr crc16_init();
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int crc16_update(IntPtr ctx, byte[] data, uint len);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int crc16_final(IntPtr ctx, ref ushort crc);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern void crc16_free(IntPtr ctx);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern IntPtr crc16_ccitt_init();
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int crc16_ccitt_update(IntPtr ctx, byte[] data, uint len);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int crc16_ccitt_final(IntPtr ctx, ref ushort crc);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern void crc16_ccitt_free(IntPtr ctx);
static void Step(ref ushort previousCrc, ushort[][] table, byte[] data, uint len)
{
// Unroll according to Intel slicing by uint8_t
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
// http://sourceforge.net/projects/slicing-by-8/
var currentPos = 0;
const int unroll = 4;
const int bytesAtOnce = 8 * unroll;
ushort crc = previousCrc;
while(len >= bytesAtOnce)
{
int unrolling;
for(unrolling = 0; unrolling < unroll; unrolling++)
{
// TODO: What trick is Microsoft doing here that's faster than arithmetic conversion
uint one = BitConverter.ToUInt32(data, currentPos) ^ crc;
currentPos += 4;
var two = BitConverter.ToUInt32(data, currentPos);
currentPos += 4;
crc = (ushort)(table[0][two >> 24 & 0xFF] ^
table[1][two >> 16 & 0xFF] ^
table[2][two >> 8 & 0xFF] ^
table[3][two & 0xFF] ^
table[4][one >> 24 & 0xFF] ^
table[5][one >> 16 & 0xFF] ^
table[6][one >> 8 & 0xFF] ^
table[7][one & 0xFF]);
}
len -= bytesAtOnce;
}
while(len-- != 0)
crc = (ushort)(crc >> 8 ^ table[0][crc & 0xFF ^ data[currentPos++]]);
previousCrc = crc;
}
static void StepInverse(ref ushort previousCrc, ushort[][] table, byte[] data, uint len)
{
// Unroll according to Intel slicing by uint8_t
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
// http://sourceforge.net/projects/slicing-by-8/
var currentPos = 0;
const int unroll = 4;
const int bytesAtOnce = 8 * unroll;
ushort crc = previousCrc;
while(len >= bytesAtOnce)
{
int unrolling;
for(unrolling = 0; unrolling < unroll; unrolling++)
{
crc = (ushort)(table[7][data[currentPos + 0] ^ crc >> 8] ^
table[6][data[currentPos + 1] ^ crc & 0xFF] ^
table[5][data[currentPos + 2]] ^
table[4][data[currentPos + 3]] ^
table[3][data[currentPos + 4]] ^
table[2][data[currentPos + 5]] ^
table[1][data[currentPos + 6]] ^
table[0][data[currentPos + 7]]);
currentPos += 8;
}
len -= bytesAtOnce;
}
while(len-- != 0)
crc = (ushort)(crc << 8 ^ table[0][crc >> 8 ^ data[currentPos++]]);
previousCrc = crc;
}
static ushort[][] GenerateTable(ushort polynomial, bool inverseTable)
{
var table = new ushort[8][];
for(var i = 0; i < 8; i++)
table[i] = new ushort[256];
if(!inverseTable)
{
for(uint i = 0; i < 256; i++)
{
uint entry = i;
for(var j = 0; j < 8; j++)
{
if((entry & 1) == 1)
entry = entry >> 1 ^ polynomial;
else
entry >>= 1;
}
table[0][i] = (ushort)entry;
}
}
else
{
for(uint i = 0; i < 256; i++)
{
uint entry = i << 8;
for(uint j = 0; j < 8; j++)
{
if((entry & 0x8000) > 0)
entry = entry << 1 ^ polynomial;
else
entry <<= 1;
table[0][i] = (ushort)entry;
}
}
}
for(var slice = 1; slice < 8; slice++)
for(var i = 0; i < 256; i++)
{
if(inverseTable)
table[slice][i] = (ushort)(table[slice - 1][i] << 8 ^ table[0][table[slice - 1][i] >> 8]);
else
table[slice][i] = (ushort)(table[slice - 1][i] >> 8 ^ table[0][table[slice - 1][i] & 0xFF]);
}
return table;
}
/// <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>
/// <param name="polynomial">CRC polynomial</param>
/// <param name="seed">CRC seed</param>
/// <param name="table">CRC lookup table</param>
/// <param name="inverse">Is CRC inverted?</param>
public static string File(string filename, out byte[] hash, ushort polynomial, ushort seed, ushort[][] table,
bool inverse)
{
bool useNative = Native.IsSupported;
bool useCcitt = polynomial == CRC16CcittContext.CRC16_CCITT_POLY &&
seed == CRC16CcittContext.CRC16_CCITT_SEED &&
inverse;
bool useIbm = polynomial == CRC16IbmContext.CRC16_IBM_POLY &&
seed == CRC16IbmContext.CRC16_IBM_SEED &&
!inverse;
IntPtr nativeContext = IntPtr.Zero;
var fileStream = new FileStream(filename, FileMode.Open);
ushort localHashInt = seed;
switch(useNative)
{
case true when useCcitt:
nativeContext = crc16_ccitt_init();
useNative = nativeContext != IntPtr.Zero;
break;
case true when useIbm:
nativeContext = crc16_init();
useNative = nativeContext != IntPtr.Zero;
break;
}
ushort[][] localTable = table ?? GenerateTable(polynomial, inverse);
var buffer = new byte[65536];
int read = fileStream.EnsureRead(buffer, 0, 65536);
while(read > 0)
{
switch(useNative)
{
case true when useCcitt:
crc16_ccitt_update(nativeContext, buffer, (uint)read);
break;
case true when useIbm:
crc16_update(nativeContext, buffer, (uint)read);
break;
default:
{
if(inverse)
StepInverse(ref localHashInt, localTable, buffer, (uint)read);
else
Step(ref localHashInt, localTable, buffer, (uint)read);
break;
}
}
read = fileStream.EnsureRead(buffer, 0, 65536);
}
localHashInt ^= seed;
switch(useNative)
{
case true when useCcitt:
crc16_ccitt_final(nativeContext, ref localHashInt);
crc16_ccitt_free(nativeContext);
break;
case true when useIbm:
crc16_final(nativeContext, ref localHashInt);
crc16_free(nativeContext);
break;
default:
{
if(inverse)
localHashInt = (ushort)~localHashInt;
break;
}
}
hash = BigEndianBitConverter.GetBytes(localHashInt);
var crc16Output = new StringBuilder();
foreach(byte h in hash)
crc16Output.Append(h.ToString("x2"));
fileStream.Close();
return crc16Output.ToString();
}
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of the data buffer to hash.</param>
/// <param name="hash">Byte array of the hash value.</param>
/// <param name="polynomial">CRC polynomial</param>
/// <param name="seed">CRC seed</param>
/// <param name="table">CRC lookup table</param>
/// <param name="inverse">Is CRC inverted?</param>
public static string Data(byte[] data, uint len, out byte[] hash, ushort polynomial, ushort seed, ushort[][] table,
bool inverse)
{
bool useNative = Native.IsSupported;
bool useCcitt = polynomial == CRC16CcittContext.CRC16_CCITT_POLY &&
seed == CRC16CcittContext.CRC16_CCITT_SEED &&
inverse;
bool useIbm = polynomial == CRC16IbmContext.CRC16_IBM_POLY &&
seed == CRC16IbmContext.CRC16_IBM_SEED &&
!inverse;
IntPtr nativeContext = IntPtr.Zero;
ushort localHashInt = seed;
switch(useNative)
{
case true when useCcitt:
nativeContext = crc16_ccitt_init();
useNative = nativeContext != IntPtr.Zero;
break;
case true when useIbm:
nativeContext = crc16_init();
useNative = nativeContext != IntPtr.Zero;
break;
}
ushort[][] localTable = table ?? GenerateTable(polynomial, inverse);
switch(useNative)
{
case true when useCcitt:
crc16_ccitt_update(nativeContext, data, len);
break;
case true when useIbm:
crc16_update(nativeContext, data, len);
break;
default:
{
if(inverse)
StepInverse(ref localHashInt, localTable, data, len);
else
Step(ref localHashInt, localTable, data, len);
break;
}
}
localHashInt ^= seed;
switch(useNative)
{
case true when useCcitt:
crc16_ccitt_final(nativeContext, ref localHashInt);
crc16_ccitt_free(nativeContext);
break;
case true when useIbm:
crc16_final(nativeContext, ref localHashInt);
crc16_free(nativeContext);
break;
default:
{
if(inverse)
localHashInt = (ushort)~localHashInt;
break;
}
}
hash = BigEndianBitConverter.GetBytes(localHashInt);
var crc16Output = new StringBuilder();
foreach(byte h in hash)
crc16Output.Append(h.ToString("x2"));
return crc16Output.ToString();
}
/// <summary>Calculates the CRC16 of the specified buffer with the specified parameters</summary>
/// <param name="buffer">Buffer</param>
/// <param name="polynomial">Polynomial</param>
/// <param name="seed">Seed</param>
/// <param name="table">Pre-generated lookup table</param>
/// <param name="inverse">Inverse CRC</param>
/// <returns>CRC16</returns>
public static ushort Calculate(byte[] buffer, ushort polynomial, ushort seed, ushort[][] table, bool inverse)
{
bool useNative = Native.IsSupported;
bool useCcitt = polynomial == CRC16CcittContext.CRC16_CCITT_POLY &&
seed == CRC16CcittContext.CRC16_CCITT_SEED &&
inverse;
bool useIbm = polynomial == CRC16IbmContext.CRC16_IBM_POLY &&
seed == CRC16IbmContext.CRC16_IBM_SEED &&
!inverse;
IntPtr nativeContext = IntPtr.Zero;
ushort localHashInt = seed;
switch(useNative)
{
case true when useCcitt:
nativeContext = crc16_ccitt_init();
useNative = nativeContext != IntPtr.Zero;
break;
case true when useIbm:
nativeContext = crc16_init();
useNative = nativeContext != IntPtr.Zero;
break;
}
ushort[][] localTable = table ?? GenerateTable(polynomial, inverse);
switch(useNative)
{
case true when useCcitt:
crc16_ccitt_update(nativeContext, buffer, (uint)buffer.Length);
break;
case true when useIbm:
crc16_update(nativeContext, buffer, (uint)buffer.Length);
break;
default:
{
if(inverse)
StepInverse(ref localHashInt, localTable, buffer, (uint)buffer.Length);
else
Step(ref localHashInt, localTable, buffer, (uint)buffer.Length);
break;
}
}
localHashInt ^= seed;
switch(useNative)
{
case true when useCcitt:
crc16_ccitt_final(nativeContext, ref localHashInt);
crc16_ccitt_free(nativeContext);
break;
case true when useIbm:
crc16_final(nativeContext, ref localHashInt);
crc16_free(nativeContext);
break;
default:
{
if(inverse)
localHashInt = (ushort)~localHashInt;
break;
}
}
return localHashInt;
}
}

View File

@@ -1,276 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : CRC16IBMContext.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Implements a CRC16 algorithm with the IBM polynomial.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
namespace Aaru.Checksums;
/// <inheritdoc />
/// <summary>Implements the CRC16 algorithm with IBM polynomial and seed</summary>
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
public sealed class CRC16IbmContext : Crc16Context
{
internal const ushort CRC16_IBM_POLY = 0xA001;
internal const ushort CRC16_IBM_SEED = 0x0000;
static readonly ushort[][] _ibmCrc16Table =
{
new ushort[]
{
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500,
0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1,
0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81,
0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540,
0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001,
0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0,
0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80,
0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700,
0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0,
0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480,
0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41,
0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01,
0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1,
0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181,
0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901,
0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1,
0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680,
0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
},
new ushort[]
{
0x0000, 0x9001, 0x6001, 0xF000, 0xC002, 0x5003, 0xA003, 0x3002, 0xC007, 0x5006, 0xA006, 0x3007, 0x0005,
0x9004, 0x6004, 0xF005, 0xC00D, 0x500C, 0xA00C, 0x300D, 0x000F, 0x900E, 0x600E, 0xF00F, 0x000A, 0x900B,
0x600B, 0xF00A, 0xC008, 0x5009, 0xA009, 0x3008, 0xC019, 0x5018, 0xA018, 0x3019, 0x001B, 0x901A, 0x601A,
0xF01B, 0x001E, 0x901F, 0x601F, 0xF01E, 0xC01C, 0x501D, 0xA01D, 0x301C, 0x0014, 0x9015, 0x6015, 0xF014,
0xC016, 0x5017, 0xA017, 0x3016, 0xC013, 0x5012, 0xA012, 0x3013, 0x0011, 0x9010, 0x6010, 0xF011, 0xC031,
0x5030, 0xA030, 0x3031, 0x0033, 0x9032, 0x6032, 0xF033, 0x0036, 0x9037, 0x6037, 0xF036, 0xC034, 0x5035,
0xA035, 0x3034, 0x003C, 0x903D, 0x603D, 0xF03C, 0xC03E, 0x503F, 0xA03F, 0x303E, 0xC03B, 0x503A, 0xA03A,
0x303B, 0x0039, 0x9038, 0x6038, 0xF039, 0x0028, 0x9029, 0x6029, 0xF028, 0xC02A, 0x502B, 0xA02B, 0x302A,
0xC02F, 0x502E, 0xA02E, 0x302F, 0x002D, 0x902C, 0x602C, 0xF02D, 0xC025, 0x5024, 0xA024, 0x3025, 0x0027,
0x9026, 0x6026, 0xF027, 0x0022, 0x9023, 0x6023, 0xF022, 0xC020, 0x5021, 0xA021, 0x3020, 0xC061, 0x5060,
0xA060, 0x3061, 0x0063, 0x9062, 0x6062, 0xF063, 0x0066, 0x9067, 0x6067, 0xF066, 0xC064, 0x5065, 0xA065,
0x3064, 0x006C, 0x906D, 0x606D, 0xF06C, 0xC06E, 0x506F, 0xA06F, 0x306E, 0xC06B, 0x506A, 0xA06A, 0x306B,
0x0069, 0x9068, 0x6068, 0xF069, 0x0078, 0x9079, 0x6079, 0xF078, 0xC07A, 0x507B, 0xA07B, 0x307A, 0xC07F,
0x507E, 0xA07E, 0x307F, 0x007D, 0x907C, 0x607C, 0xF07D, 0xC075, 0x5074, 0xA074, 0x3075, 0x0077, 0x9076,
0x6076, 0xF077, 0x0072, 0x9073, 0x6073, 0xF072, 0xC070, 0x5071, 0xA071, 0x3070, 0x0050, 0x9051, 0x6051,
0xF050, 0xC052, 0x5053, 0xA053, 0x3052, 0xC057, 0x5056, 0xA056, 0x3057, 0x0055, 0x9054, 0x6054, 0xF055,
0xC05D, 0x505C, 0xA05C, 0x305D, 0x005F, 0x905E, 0x605E, 0xF05F, 0x005A, 0x905B, 0x605B, 0xF05A, 0xC058,
0x5059, 0xA059, 0x3058, 0xC049, 0x5048, 0xA048, 0x3049, 0x004B, 0x904A, 0x604A, 0xF04B, 0x004E, 0x904F,
0x604F, 0xF04E, 0xC04C, 0x504D, 0xA04D, 0x304C, 0x0044, 0x9045, 0x6045, 0xF044, 0xC046, 0x5047, 0xA047,
0x3046, 0xC043, 0x5042, 0xA042, 0x3043, 0x0041, 0x9040, 0x6040, 0xF041
},
new ushort[]
{
0x0000, 0xC051, 0xC0A1, 0x00F0, 0xC141, 0x0110, 0x01E0, 0xC1B1, 0xC281, 0x02D0, 0x0220, 0xC271, 0x03C0,
0xC391, 0xC361, 0x0330, 0xC501, 0x0550, 0x05A0, 0xC5F1, 0x0440, 0xC411, 0xC4E1, 0x04B0, 0x0780, 0xC7D1,
0xC721, 0x0770, 0xC6C1, 0x0690, 0x0660, 0xC631, 0xCA01, 0x0A50, 0x0AA0, 0xCAF1, 0x0B40, 0xCB11, 0xCBE1,
0x0BB0, 0x0880, 0xC8D1, 0xC821, 0x0870, 0xC9C1, 0x0990, 0x0960, 0xC931, 0x0F00, 0xCF51, 0xCFA1, 0x0FF0,
0xCE41, 0x0E10, 0x0EE0, 0xCEB1, 0xCD81, 0x0DD0, 0x0D20, 0xCD71, 0x0CC0, 0xCC91, 0xCC61, 0x0C30, 0xD401,
0x1450, 0x14A0, 0xD4F1, 0x1540, 0xD511, 0xD5E1, 0x15B0, 0x1680, 0xD6D1, 0xD621, 0x1670, 0xD7C1, 0x1790,
0x1760, 0xD731, 0x1100, 0xD151, 0xD1A1, 0x11F0, 0xD041, 0x1010, 0x10E0, 0xD0B1, 0xD381, 0x13D0, 0x1320,
0xD371, 0x12C0, 0xD291, 0xD261, 0x1230, 0x1E00, 0xDE51, 0xDEA1, 0x1EF0, 0xDF41, 0x1F10, 0x1FE0, 0xDFB1,
0xDC81, 0x1CD0, 0x1C20, 0xDC71, 0x1DC0, 0xDD91, 0xDD61, 0x1D30, 0xDB01, 0x1B50, 0x1BA0, 0xDBF1, 0x1A40,
0xDA11, 0xDAE1, 0x1AB0, 0x1980, 0xD9D1, 0xD921, 0x1970, 0xD8C1, 0x1890, 0x1860, 0xD831, 0xE801, 0x2850,
0x28A0, 0xE8F1, 0x2940, 0xE911, 0xE9E1, 0x29B0, 0x2A80, 0xEAD1, 0xEA21, 0x2A70, 0xEBC1, 0x2B90, 0x2B60,
0xEB31, 0x2D00, 0xED51, 0xEDA1, 0x2DF0, 0xEC41, 0x2C10, 0x2CE0, 0xECB1, 0xEF81, 0x2FD0, 0x2F20, 0xEF71,
0x2EC0, 0xEE91, 0xEE61, 0x2E30, 0x2200, 0xE251, 0xE2A1, 0x22F0, 0xE341, 0x2310, 0x23E0, 0xE3B1, 0xE081,
0x20D0, 0x2020, 0xE071, 0x21C0, 0xE191, 0xE161, 0x2130, 0xE701, 0x2750, 0x27A0, 0xE7F1, 0x2640, 0xE611,
0xE6E1, 0x26B0, 0x2580, 0xE5D1, 0xE521, 0x2570, 0xE4C1, 0x2490, 0x2460, 0xE431, 0x3C00, 0xFC51, 0xFCA1,
0x3CF0, 0xFD41, 0x3D10, 0x3DE0, 0xFDB1, 0xFE81, 0x3ED0, 0x3E20, 0xFE71, 0x3FC0, 0xFF91, 0xFF61, 0x3F30,
0xF901, 0x3950, 0x39A0, 0xF9F1, 0x3840, 0xF811, 0xF8E1, 0x38B0, 0x3B80, 0xFBD1, 0xFB21, 0x3B70, 0xFAC1,
0x3A90, 0x3A60, 0xFA31, 0xF601, 0x3650, 0x36A0, 0xF6F1, 0x3740, 0xF711, 0xF7E1, 0x37B0, 0x3480, 0xF4D1,
0xF421, 0x3470, 0xF5C1, 0x3590, 0x3560, 0xF531, 0x3300, 0xF351, 0xF3A1, 0x33F0, 0xF241, 0x3210, 0x32E0,
0xF2B1, 0xF181, 0x31D0, 0x3120, 0xF171, 0x30C0, 0xF091, 0xF061, 0x3030
},
new ushort[]
{
0x0000, 0xFC01, 0xB801, 0x4400, 0x3001, 0xCC00, 0x8800, 0x7401, 0x6002, 0x9C03, 0xD803, 0x2402, 0x5003,
0xAC02, 0xE802, 0x1403, 0xC004, 0x3C05, 0x7805, 0x8404, 0xF005, 0x0C04, 0x4804, 0xB405, 0xA006, 0x5C07,
0x1807, 0xE406, 0x9007, 0x6C06, 0x2806, 0xD407, 0xC00B, 0x3C0A, 0x780A, 0x840B, 0xF00A, 0x0C0B, 0x480B,
0xB40A, 0xA009, 0x5C08, 0x1808, 0xE409, 0x9008, 0x6C09, 0x2809, 0xD408, 0x000F, 0xFC0E, 0xB80E, 0x440F,
0x300E, 0xCC0F, 0x880F, 0x740E, 0x600D, 0x9C0C, 0xD80C, 0x240D, 0x500C, 0xAC0D, 0xE80D, 0x140C, 0xC015,
0x3C14, 0x7814, 0x8415, 0xF014, 0x0C15, 0x4815, 0xB414, 0xA017, 0x5C16, 0x1816, 0xE417, 0x9016, 0x6C17,
0x2817, 0xD416, 0x0011, 0xFC10, 0xB810, 0x4411, 0x3010, 0xCC11, 0x8811, 0x7410, 0x6013, 0x9C12, 0xD812,
0x2413, 0x5012, 0xAC13, 0xE813, 0x1412, 0x001E, 0xFC1F, 0xB81F, 0x441E, 0x301F, 0xCC1E, 0x881E, 0x741F,
0x601C, 0x9C1D, 0xD81D, 0x241C, 0x501D, 0xAC1C, 0xE81C, 0x141D, 0xC01A, 0x3C1B, 0x781B, 0x841A, 0xF01B,
0x0C1A, 0x481A, 0xB41B, 0xA018, 0x5C19, 0x1819, 0xE418, 0x9019, 0x6C18, 0x2818, 0xD419, 0xC029, 0x3C28,
0x7828, 0x8429, 0xF028, 0x0C29, 0x4829, 0xB428, 0xA02B, 0x5C2A, 0x182A, 0xE42B, 0x902A, 0x6C2B, 0x282B,
0xD42A, 0x002D, 0xFC2C, 0xB82C, 0x442D, 0x302C, 0xCC2D, 0x882D, 0x742C, 0x602F, 0x9C2E, 0xD82E, 0x242F,
0x502E, 0xAC2F, 0xE82F, 0x142E, 0x0022, 0xFC23, 0xB823, 0x4422, 0x3023, 0xCC22, 0x8822, 0x7423, 0x6020,
0x9C21, 0xD821, 0x2420, 0x5021, 0xAC20, 0xE820, 0x1421, 0xC026, 0x3C27, 0x7827, 0x8426, 0xF027, 0x0C26,
0x4826, 0xB427, 0xA024, 0x5C25, 0x1825, 0xE424, 0x9025, 0x6C24, 0x2824, 0xD425, 0x003C, 0xFC3D, 0xB83D,
0x443C, 0x303D, 0xCC3C, 0x883C, 0x743D, 0x603E, 0x9C3F, 0xD83F, 0x243E, 0x503F, 0xAC3E, 0xE83E, 0x143F,
0xC038, 0x3C39, 0x7839, 0x8438, 0xF039, 0x0C38, 0x4838, 0xB439, 0xA03A, 0x5C3B, 0x183B, 0xE43A, 0x903B,
0x6C3A, 0x283A, 0xD43B, 0xC037, 0x3C36, 0x7836, 0x8437, 0xF036, 0x0C37, 0x4837, 0xB436, 0xA035, 0x5C34,
0x1834, 0xE435, 0x9034, 0x6C35, 0x2835, 0xD434, 0x0033, 0xFC32, 0xB832, 0x4433, 0x3032, 0xCC33, 0x8833,
0x7432, 0x6031, 0x9C30, 0xD830, 0x2431, 0x5030, 0xAC31, 0xE831, 0x1430
},
new ushort[]
{
0x0000, 0xC03D, 0xC079, 0x0044, 0xC0F1, 0x00CC, 0x0088, 0xC0B5, 0xC1E1, 0x01DC, 0x0198, 0xC1A5, 0x0110,
0xC12D, 0xC169, 0x0154, 0xC3C1, 0x03FC, 0x03B8, 0xC385, 0x0330, 0xC30D, 0xC349, 0x0374, 0x0220, 0xC21D,
0xC259, 0x0264, 0xC2D1, 0x02EC, 0x02A8, 0xC295, 0xC781, 0x07BC, 0x07F8, 0xC7C5, 0x0770, 0xC74D, 0xC709,
0x0734, 0x0660, 0xC65D, 0xC619, 0x0624, 0xC691, 0x06AC, 0x06E8, 0xC6D5, 0x0440, 0xC47D, 0xC439, 0x0404,
0xC4B1, 0x048C, 0x04C8, 0xC4F5, 0xC5A1, 0x059C, 0x05D8, 0xC5E5, 0x0550, 0xC56D, 0xC529, 0x0514, 0xCF01,
0x0F3C, 0x0F78, 0xCF45, 0x0FF0, 0xCFCD, 0xCF89, 0x0FB4, 0x0EE0, 0xCEDD, 0xCE99, 0x0EA4, 0xCE11, 0x0E2C,
0x0E68, 0xCE55, 0x0CC0, 0xCCFD, 0xCCB9, 0x0C84, 0xCC31, 0x0C0C, 0x0C48, 0xCC75, 0xCD21, 0x0D1C, 0x0D58,
0xCD65, 0x0DD0, 0xCDED, 0xCDA9, 0x0D94, 0x0880, 0xC8BD, 0xC8F9, 0x08C4, 0xC871, 0x084C, 0x0808, 0xC835,
0xC961, 0x095C, 0x0918, 0xC925, 0x0990, 0xC9AD, 0xC9E9, 0x09D4, 0xCB41, 0x0B7C, 0x0B38, 0xCB05, 0x0BB0,
0xCB8D, 0xCBC9, 0x0BF4, 0x0AA0, 0xCA9D, 0xCAD9, 0x0AE4, 0xCA51, 0x0A6C, 0x0A28, 0xCA15, 0xDE01, 0x1E3C,
0x1E78, 0xDE45, 0x1EF0, 0xDECD, 0xDE89, 0x1EB4, 0x1FE0, 0xDFDD, 0xDF99, 0x1FA4, 0xDF11, 0x1F2C, 0x1F68,
0xDF55, 0x1DC0, 0xDDFD, 0xDDB9, 0x1D84, 0xDD31, 0x1D0C, 0x1D48, 0xDD75, 0xDC21, 0x1C1C, 0x1C58, 0xDC65,
0x1CD0, 0xDCED, 0xDCA9, 0x1C94, 0x1980, 0xD9BD, 0xD9F9, 0x19C4, 0xD971, 0x194C, 0x1908, 0xD935, 0xD861,
0x185C, 0x1818, 0xD825, 0x1890, 0xD8AD, 0xD8E9, 0x18D4, 0xDA41, 0x1A7C, 0x1A38, 0xDA05, 0x1AB0, 0xDA8D,
0xDAC9, 0x1AF4, 0x1BA0, 0xDB9D, 0xDBD9, 0x1BE4, 0xDB51, 0x1B6C, 0x1B28, 0xDB15, 0x1100, 0xD13D, 0xD179,
0x1144, 0xD1F1, 0x11CC, 0x1188, 0xD1B5, 0xD0E1, 0x10DC, 0x1098, 0xD0A5, 0x1010, 0xD02D, 0xD069, 0x1054,
0xD2C1, 0x12FC, 0x12B8, 0xD285, 0x1230, 0xD20D, 0xD249, 0x1274, 0x1320, 0xD31D, 0xD359, 0x1364, 0xD3D1,
0x13EC, 0x13A8, 0xD395, 0xD681, 0x16BC, 0x16F8, 0xD6C5, 0x1670, 0xD64D, 0xD609, 0x1634, 0x1760, 0xD75D,
0xD719, 0x1724, 0xD791, 0x17AC, 0x17E8, 0xD7D5, 0x1540, 0xD57D, 0xD539, 0x1504, 0xD5B1, 0x158C, 0x15C8,
0xD5F5, 0xD4A1, 0x149C, 0x14D8, 0xD4E5, 0x1450, 0xD46D, 0xD429, 0x1414
},
new ushort[]
{
0x0000, 0xD101, 0xE201, 0x3300, 0x8401, 0x5500, 0x6600, 0xB701, 0x4801, 0x9900, 0xAA00, 0x7B01, 0xCC00,
0x1D01, 0x2E01, 0xFF00, 0x9002, 0x4103, 0x7203, 0xA302, 0x1403, 0xC502, 0xF602, 0x2703, 0xD803, 0x0902,
0x3A02, 0xEB03, 0x5C02, 0x8D03, 0xBE03, 0x6F02, 0x6007, 0xB106, 0x8206, 0x5307, 0xE406, 0x3507, 0x0607,
0xD706, 0x2806, 0xF907, 0xCA07, 0x1B06, 0xAC07, 0x7D06, 0x4E06, 0x9F07, 0xF005, 0x2104, 0x1204, 0xC305,
0x7404, 0xA505, 0x9605, 0x4704, 0xB804, 0x6905, 0x5A05, 0x8B04, 0x3C05, 0xED04, 0xDE04, 0x0F05, 0xC00E,
0x110F, 0x220F, 0xF30E, 0x440F, 0x950E, 0xA60E, 0x770F, 0x880F, 0x590E, 0x6A0E, 0xBB0F, 0x0C0E, 0xDD0F,
0xEE0F, 0x3F0E, 0x500C, 0x810D, 0xB20D, 0x630C, 0xD40D, 0x050C, 0x360C, 0xE70D, 0x180D, 0xC90C, 0xFA0C,
0x2B0D, 0x9C0C, 0x4D0D, 0x7E0D, 0xAF0C, 0xA009, 0x7108, 0x4208, 0x9309, 0x2408, 0xF509, 0xC609, 0x1708,
0xE808, 0x3909, 0x0A09, 0xDB08, 0x6C09, 0xBD08, 0x8E08, 0x5F09, 0x300B, 0xE10A, 0xD20A, 0x030B, 0xB40A,
0x650B, 0x560B, 0x870A, 0x780A, 0xA90B, 0x9A0B, 0x4B0A, 0xFC0B, 0x2D0A, 0x1E0A, 0xCF0B, 0xC01F, 0x111E,
0x221E, 0xF31F, 0x441E, 0x951F, 0xA61F, 0x771E, 0x881E, 0x591F, 0x6A1F, 0xBB1E, 0x0C1F, 0xDD1E, 0xEE1E,
0x3F1F, 0x501D, 0x811C, 0xB21C, 0x631D, 0xD41C, 0x051D, 0x361D, 0xE71C, 0x181C, 0xC91D, 0xFA1D, 0x2B1C,
0x9C1D, 0x4D1C, 0x7E1C, 0xAF1D, 0xA018, 0x7119, 0x4219, 0x9318, 0x2419, 0xF518, 0xC618, 0x1719, 0xE819,
0x3918, 0x0A18, 0xDB19, 0x6C18, 0xBD19, 0x8E19, 0x5F18, 0x301A, 0xE11B, 0xD21B, 0x031A, 0xB41B, 0x651A,
0x561A, 0x871B, 0x781B, 0xA91A, 0x9A1A, 0x4B1B, 0xFC1A, 0x2D1B, 0x1E1B, 0xCF1A, 0x0011, 0xD110, 0xE210,
0x3311, 0x8410, 0x5511, 0x6611, 0xB710, 0x4810, 0x9911, 0xAA11, 0x7B10, 0xCC11, 0x1D10, 0x2E10, 0xFF11,
0x9013, 0x4112, 0x7212, 0xA313, 0x1412, 0xC513, 0xF613, 0x2712, 0xD812, 0x0913, 0x3A13, 0xEB12, 0x5C13,
0x8D12, 0xBE12, 0x6F13, 0x6016, 0xB117, 0x8217, 0x5316, 0xE417, 0x3516, 0x0616, 0xD717, 0x2817, 0xF916,
0xCA16, 0x1B17, 0xAC16, 0x7D17, 0x4E17, 0x9F16, 0xF014, 0x2115, 0x1215, 0xC314, 0x7415, 0xA514, 0x9614,
0x4715, 0xB815, 0x6914, 0x5A14, 0x8B15, 0x3C14, 0xED15, 0xDE15, 0x0F14
},
new ushort[]
{
0x0000, 0xC010, 0xC023, 0x0033, 0xC045, 0x0055, 0x0066, 0xC076, 0xC089, 0x0099, 0x00AA, 0xC0BA, 0x00CC,
0xC0DC, 0xC0EF, 0x00FF, 0xC111, 0x0101, 0x0132, 0xC122, 0x0154, 0xC144, 0xC177, 0x0167, 0x0198, 0xC188,
0xC1BB, 0x01AB, 0xC1DD, 0x01CD, 0x01FE, 0xC1EE, 0xC221, 0x0231, 0x0202, 0xC212, 0x0264, 0xC274, 0xC247,
0x0257, 0x02A8, 0xC2B8, 0xC28B, 0x029B, 0xC2ED, 0x02FD, 0x02CE, 0xC2DE, 0x0330, 0xC320, 0xC313, 0x0303,
0xC375, 0x0365, 0x0356, 0xC346, 0xC3B9, 0x03A9, 0x039A, 0xC38A, 0x03FC, 0xC3EC, 0xC3DF, 0x03CF, 0xC441,
0x0451, 0x0462, 0xC472, 0x0404, 0xC414, 0xC427, 0x0437, 0x04C8, 0xC4D8, 0xC4EB, 0x04FB, 0xC48D, 0x049D,
0x04AE, 0xC4BE, 0x0550, 0xC540, 0xC573, 0x0563, 0xC515, 0x0505, 0x0536, 0xC526, 0xC5D9, 0x05C9, 0x05FA,
0xC5EA, 0x059C, 0xC58C, 0xC5BF, 0x05AF, 0x0660, 0xC670, 0xC643, 0x0653, 0xC625, 0x0635, 0x0606, 0xC616,
0xC6E9, 0x06F9, 0x06CA, 0xC6DA, 0x06AC, 0xC6BC, 0xC68F, 0x069F, 0xC771, 0x0761, 0x0752, 0xC742, 0x0734,
0xC724, 0xC717, 0x0707, 0x07F8, 0xC7E8, 0xC7DB, 0x07CB, 0xC7BD, 0x07AD, 0x079E, 0xC78E, 0xC881, 0x0891,
0x08A2, 0xC8B2, 0x08C4, 0xC8D4, 0xC8E7, 0x08F7, 0x0808, 0xC818, 0xC82B, 0x083B, 0xC84D, 0x085D, 0x086E,
0xC87E, 0x0990, 0xC980, 0xC9B3, 0x09A3, 0xC9D5, 0x09C5, 0x09F6, 0xC9E6, 0xC919, 0x0909, 0x093A, 0xC92A,
0x095C, 0xC94C, 0xC97F, 0x096F, 0x0AA0, 0xCAB0, 0xCA83, 0x0A93, 0xCAE5, 0x0AF5, 0x0AC6, 0xCAD6, 0xCA29,
0x0A39, 0x0A0A, 0xCA1A, 0x0A6C, 0xCA7C, 0xCA4F, 0x0A5F, 0xCBB1, 0x0BA1, 0x0B92, 0xCB82, 0x0BF4, 0xCBE4,
0xCBD7, 0x0BC7, 0x0B38, 0xCB28, 0xCB1B, 0x0B0B, 0xCB7D, 0x0B6D, 0x0B5E, 0xCB4E, 0x0CC0, 0xCCD0, 0xCCE3,
0x0CF3, 0xCC85, 0x0C95, 0x0CA6, 0xCCB6, 0xCC49, 0x0C59, 0x0C6A, 0xCC7A, 0x0C0C, 0xCC1C, 0xCC2F, 0x0C3F,
0xCDD1, 0x0DC1, 0x0DF2, 0xCDE2, 0x0D94, 0xCD84, 0xCDB7, 0x0DA7, 0x0D58, 0xCD48, 0xCD7B, 0x0D6B, 0xCD1D,
0x0D0D, 0x0D3E, 0xCD2E, 0xCEE1, 0x0EF1, 0x0EC2, 0xCED2, 0x0EA4, 0xCEB4, 0xCE87, 0x0E97, 0x0E68, 0xCE78,
0xCE4B, 0x0E5B, 0xCE2D, 0x0E3D, 0x0E0E, 0xCE1E, 0x0FF0, 0xCFE0, 0xCFD3, 0x0FC3, 0xCFB5, 0x0FA5, 0x0F96,
0xCF86, 0xCF79, 0x0F69, 0x0F5A, 0xCF4A, 0x0F3C, 0xCF2C, 0xCF1F, 0x0F0F
},
new ushort[]
{
0x0000, 0xCCC1, 0xD981, 0x1540, 0xF301, 0x3FC0, 0x2A80, 0xE641, 0xA601, 0x6AC0, 0x7F80, 0xB341, 0x5500,
0x99C1, 0x8C81, 0x4040, 0x0C01, 0xC0C0, 0xD580, 0x1941, 0xFF00, 0x33C1, 0x2681, 0xEA40, 0xAA00, 0x66C1,
0x7381, 0xBF40, 0x5901, 0x95C0, 0x8080, 0x4C41, 0x1802, 0xD4C3, 0xC183, 0x0D42, 0xEB03, 0x27C2, 0x3282,
0xFE43, 0xBE03, 0x72C2, 0x6782, 0xAB43, 0x4D02, 0x81C3, 0x9483, 0x5842, 0x1403, 0xD8C2, 0xCD82, 0x0143,
0xE702, 0x2BC3, 0x3E83, 0xF242, 0xB202, 0x7EC3, 0x6B83, 0xA742, 0x4103, 0x8DC2, 0x9882, 0x5443, 0x3004,
0xFCC5, 0xE985, 0x2544, 0xC305, 0x0FC4, 0x1A84, 0xD645, 0x9605, 0x5AC4, 0x4F84, 0x8345, 0x6504, 0xA9C5,
0xBC85, 0x7044, 0x3C05, 0xF0C4, 0xE584, 0x2945, 0xCF04, 0x03C5, 0x1685, 0xDA44, 0x9A04, 0x56C5, 0x4385,
0x8F44, 0x6905, 0xA5C4, 0xB084, 0x7C45, 0x2806, 0xE4C7, 0xF187, 0x3D46, 0xDB07, 0x17C6, 0x0286, 0xCE47,
0x8E07, 0x42C6, 0x5786, 0x9B47, 0x7D06, 0xB1C7, 0xA487, 0x6846, 0x2407, 0xE8C6, 0xFD86, 0x3147, 0xD706,
0x1BC7, 0x0E87, 0xC246, 0x8206, 0x4EC7, 0x5B87, 0x9746, 0x7107, 0xBDC6, 0xA886, 0x6447, 0x6008, 0xACC9,
0xB989, 0x7548, 0x9309, 0x5FC8, 0x4A88, 0x8649, 0xC609, 0x0AC8, 0x1F88, 0xD349, 0x3508, 0xF9C9, 0xEC89,
0x2048, 0x6C09, 0xA0C8, 0xB588, 0x7949, 0x9F08, 0x53C9, 0x4689, 0x8A48, 0xCA08, 0x06C9, 0x1389, 0xDF48,
0x3909, 0xF5C8, 0xE088, 0x2C49, 0x780A, 0xB4CB, 0xA18B, 0x6D4A, 0x8B0B, 0x47CA, 0x528A, 0x9E4B, 0xDE0B,
0x12CA, 0x078A, 0xCB4B, 0x2D0A, 0xE1CB, 0xF48B, 0x384A, 0x740B, 0xB8CA, 0xAD8A, 0x614B, 0x870A, 0x4BCB,
0x5E8B, 0x924A, 0xD20A, 0x1ECB, 0x0B8B, 0xC74A, 0x210B, 0xEDCA, 0xF88A, 0x344B, 0x500C, 0x9CCD, 0x898D,
0x454C, 0xA30D, 0x6FCC, 0x7A8C, 0xB64D, 0xF60D, 0x3ACC, 0x2F8C, 0xE34D, 0x050C, 0xC9CD, 0xDC8D, 0x104C,
0x5C0D, 0x90CC, 0x858C, 0x494D, 0xAF0C, 0x63CD, 0x768D, 0xBA4C, 0xFA0C, 0x36CD, 0x238D, 0xEF4C, 0x090D,
0xC5CC, 0xD08C, 0x1C4D, 0x480E, 0x84CF, 0x918F, 0x5D4E, 0xBB0F, 0x77CE, 0x628E, 0xAE4F, 0xEE0F, 0x22CE,
0x378E, 0xFB4F, 0x1D0E, 0xD1CF, 0xC48F, 0x084E, 0x440F, 0x88CE, 0x9D8E, 0x514F, 0xB70E, 0x7BCF, 0x6E8F,
0xA24E, 0xE20E, 0x2ECF, 0x3B8F, 0xF74E, 0x110F, 0xDDCE, 0xC88E, 0x044F
}
};
/// <summary>Initializes an instance of the CRC16 with IBM polynomial and seed.</summary>
/// <inheritdoc />
public CRC16IbmContext() : base(CRC16_IBM_POLY, CRC16_IBM_SEED, _ibmCrc16Table, false) {}
/// <inheritdoc />
public new string Name => "CRC-16 (IBM)";
/// <inheritdoc />
public new Guid Id => new("0470433E-0C78-4C37-8C9F-BD8E72340E78");
/// <inheritdoc />
public new string Author => "Natalia Portillo";
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
public static byte[] File(string filename)
{
File(filename, out byte[] hash);
return hash;
}
/// <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) =>
File(filename, out hash, CRC16_IBM_POLY, CRC16_IBM_SEED, _ibmCrc16Table, false);
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of the data buffer to hash.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, uint len, out byte[] hash) =>
Data(data, len, out hash, CRC16_IBM_POLY, CRC16_IBM_SEED, _ibmCrc16Table, false);
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
}

View File

@@ -1,136 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : arm_simd.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
// The Chromium Authors
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Compute CRC32 checksum using ARM special instructions..
//
// --[ License ] --------------------------------------------------------------
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// Copyright 2017 The Chromium Authors. All rights reserved.
// ****************************************************************************/
#if NET5_0_OR_GREATER
using System;
using System.Runtime.Intrinsics.Arm;
namespace Aaru.Checksums.CRC32;
static class ArmSimd
{
internal static uint Step64(byte[] buf, long len, uint crc)
{
uint c = crc;
var bufPos = 0;
while(len >= 64)
{
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
len -= 64;
}
while(len >= 8)
{
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
bufPos += 8;
len -= 8;
}
while(len-- > 0)
c = Crc32.ComputeCrc32(c, buf[bufPos++]);
return c;
}
internal static uint Step32(byte[] buf, long len, uint crc)
{
uint c = crc;
var bufPos = 0;
while(len >= 32)
{
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
len -= 32;
}
while(len >= 4)
{
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
bufPos += 4;
len -= 4;
}
while(len-- > 0)
c = Crc32.ComputeCrc32(c, buf[bufPos++]);
return c;
}
}
#endif

View File

@@ -1,227 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : clmul.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
// Wajdi Feghali <wajdi.k.feghali@intel.com>
// Jim Guilford <james.guilford@intel.com>
// Vinodh Gopal <vinodh.gopal@intel.com>
// Erdinc Ozturk <erdinc.ozturk@intel.com>
// Jim Kukunas <james.t.kukunas@linux.intel.com>
// Marian Beermann
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ
// instruction.
//
// A white paper describing this algorithm can be found at:
// http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
//
// --[ License ] --------------------------------------------------------------
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from
// the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// Copyright (c) 2016 Marian Beermann (add support for initial value, restructuring)
// Copyright (C) 2013 Intel Corporation. All rights reserved.
// ****************************************************************************/
#if NETCOREAPP3_1_OR_GREATER
using System;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
namespace Aaru.Checksums.CRC32;
static class Clmul
{
static readonly uint[] _crcK =
{
0xccaa009e, 0x00000000, /* rk1 */ 0x751997d0, 0x00000001, /* rk2 */ 0xccaa009e, 0x00000000, /* rk5 */
0x63cd6124, 0x00000001, /* rk6 */ 0xf7011640, 0x00000001, /* rk7 */ 0xdb710640, 0x00000001 /* rk8 */
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void Fold4(ref Vector128<uint> xmmCRC0, ref Vector128<uint> xmmCRC1, ref Vector128<uint> xmmCRC2,
ref Vector128<uint> xmmCRC3)
{
var xmmFold4 = Vector128.Create(0xc6e41596, 0x00000001, 0x54442bd4, 0x00000001);
Vector128<uint> xTmp0 = xmmCRC0;
Vector128<uint> xTmp1 = xmmCRC1;
Vector128<uint> xTmp2 = xmmCRC2;
Vector128<uint> xTmp3 = xmmCRC3;
xmmCRC0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
xTmp0 = Pclmulqdq.CarrylessMultiply(xTmp0.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
Vector128<float> psCRC0 = xmmCRC0.AsSingle();
Vector128<float> psT0 = xTmp0.AsSingle();
Vector128<float> psRes0 = Sse.Xor(psCRC0, psT0);
xmmCRC1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
xTmp1 = Pclmulqdq.CarrylessMultiply(xTmp1.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
Vector128<float> psCRC1 = xmmCRC1.AsSingle();
Vector128<float> psT1 = xTmp1.AsSingle();
Vector128<float> psRes1 = Sse.Xor(psCRC1, psT1);
xmmCRC2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
xTmp2 = Pclmulqdq.CarrylessMultiply(xTmp2.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
Vector128<float> psCRC2 = xmmCRC2.AsSingle();
Vector128<float> psT2 = xTmp2.AsSingle();
Vector128<float> psRes2 = Sse.Xor(psCRC2, psT2);
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
xTmp3 = Pclmulqdq.CarrylessMultiply(xTmp3.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
Vector128<float> psCRC3 = xmmCRC3.AsSingle();
Vector128<float> psT3 = xTmp3.AsSingle();
Vector128<float> psRes3 = Sse.Xor(psCRC3, psT3);
xmmCRC0 = psRes0.AsUInt32();
xmmCRC1 = psRes1.AsUInt32();
xmmCRC2 = psRes2.AsUInt32();
xmmCRC3 = psRes3.AsUInt32();
}
internal static uint Step(byte[] src, long len, uint initialCRC)
{
Vector128<uint> xmmInitial = Sse2.ConvertScalarToVector128UInt32(initialCRC);
Vector128<uint> xmmCRC0 = Sse2.ConvertScalarToVector128UInt32(0x9db42487);
Vector128<uint> xmmCRC1 = Vector128<uint>.Zero;
Vector128<uint> xmmCRC2 = Vector128<uint>.Zero;
Vector128<uint> xmmCRC3 = Vector128<uint>.Zero;
var bufPos = 0;
var first = true;
/* fold 512 to 32 step variable declarations for ISO-C90 compat. */
var xmmMask = Vector128.Create(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000);
var xmmMask2 = Vector128.Create(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
while((len -= 64) >= 0)
{
var xmmT0 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8),
BitConverter.ToUInt32(src, bufPos + 12));
bufPos += 16;
var xmmT1 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8),
BitConverter.ToUInt32(src, bufPos + 12));
bufPos += 16;
var xmmT2 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8),
BitConverter.ToUInt32(src, bufPos + 12));
bufPos += 16;
var xmmT3 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8),
BitConverter.ToUInt32(src, bufPos + 12));
bufPos += 16;
if(first)
{
first = false;
xmmT0 = Sse2.Xor(xmmT0, xmmInitial);
}
Fold4(ref xmmCRC0, ref xmmCRC1, ref xmmCRC2, ref xmmCRC3);
xmmCRC0 = Sse2.Xor(xmmCRC0, xmmT0);
xmmCRC1 = Sse2.Xor(xmmCRC1, xmmT1);
xmmCRC2 = Sse2.Xor(xmmCRC2, xmmT2);
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmT3);
}
/* fold 512 to 32 */
/*
* k1
*/
var crcFold = Vector128.Create(_crcK[0], _crcK[1], _crcK[2], _crcK[3]);
Vector128<uint> xTmp0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
xmmCRC0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
xmmCRC1 = Sse2.Xor(xmmCRC1, xTmp0);
xmmCRC1 = Sse2.Xor(xmmCRC1, xmmCRC0);
Vector128<uint> xTmp1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
xmmCRC1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
xmmCRC2 = Sse2.Xor(xmmCRC2, xTmp1);
xmmCRC2 = Sse2.Xor(xmmCRC2, xmmCRC1);
Vector128<uint> xTmp2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
xmmCRC2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
xmmCRC3 = Sse2.Xor(xmmCRC3, xTmp2);
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
/*
* k5
*/
crcFold = Vector128.Create(_crcK[4], _crcK[5], _crcK[6], _crcK[7]);
xmmCRC0 = xmmCRC3;
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0).AsUInt32();
xmmCRC0 = Sse2.ShiftRightLogical128BitLane(xmmCRC0, 8);
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC0);
xmmCRC0 = xmmCRC3;
xmmCRC3 = Sse2.ShiftLeftLogical128BitLane(xmmCRC3, 4);
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC0);
xmmCRC3 = Sse2.And(xmmCRC3, xmmMask2);
/*
* k7
*/
xmmCRC1 = xmmCRC3;
xmmCRC2 = xmmCRC3;
crcFold = Vector128.Create(_crcK[8], _crcK[9], _crcK[10], _crcK[11]);
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0).AsUInt32();
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
xmmCRC3 = Sse2.And(xmmCRC3, xmmMask);
xmmCRC2 = xmmCRC3;
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC1);
/*
* could just as well write xmm_crc3[2], doing a movaps and truncating, but
* no real advantage - it's a tiny bit slower per call, while no additional CPUs
* would be supported by only requiring SSSE3 and CLMUL instead of SSE4.1 + CLMUL
*/
return ~Sse41.Extract(xmmCRC3, 2);
}
}
#endif

View File

@@ -1,671 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : CRC32Context.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Implements a CRC32 algorithm.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
#if NET5_0_OR_GREATER
using System.Runtime.Intrinsics.Arm;
#endif
#if NETCOREAPP3_1_OR_GREATER
using System.Runtime.Intrinsics.X86;
#endif
using System.Text;
#if NETCOREAPP3_1_OR_GREATER
using Aaru.Checksums.CRC32;
#endif
using Aaru.CommonTypes.Interfaces;
using Aaru.Helpers;
namespace Aaru.Checksums;
/// <inheritdoc />
/// <summary>Implements a CRC32 algorithm</summary>
[SuppressMessage("ReSharper", "UnusedMember.Global")]
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public sealed class Crc32Context : IChecksum
{
const uint CRC32_ISO_POLY = 0xEDB88320;
const uint CRC32_ISO_SEED = 0xFFFFFFFF;
internal static readonly uint[][] ISOCrc32Table =
{
new uint[]
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832,
0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A,
0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4,
0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074,
0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525,
0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76,
0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6,
0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7,
0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330,
0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
},
new uint[]
{
0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3, 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7, 0xC8D98A08,
0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB, 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF, 0x4AC21251, 0x53D92310,
0x78F470D3, 0x61EF4192, 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496, 0x821B9859, 0x9B00A918, 0xB02DFADB,
0xA936CB9A, 0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E, 0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761,
0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265, 0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69, 0x39316BAE,
0x202A5AEF, 0x0B07092C, 0x121C386D, 0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530, 0xBB2AF3F7, 0xA231C2B6,
0x891C9175, 0x9007A034, 0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38, 0x73F379FF, 0x6AE848BE, 0x41C51B7D,
0x58DE2A3C, 0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6, 0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2,
0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE, 0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA, 0xBABB5D54,
0xA3A06C15, 0x888D3FD6, 0x91960E97, 0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93, 0x7262D75C, 0x6B79E61D,
0x4054B5DE, 0x594F849F, 0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B, 0x65FD6BA7, 0x7CE65AE6, 0x57CB0925,
0x4ED03864, 0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60, 0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C,
0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768, 0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35, 0x4B53BCF2,
0x52488DB3, 0x7965DE70, 0x607EEF31, 0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D, 0x838A36FA, 0x9A9107BB,
0xB1BC5478, 0xA8A76539, 0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88, 0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD,
0x74C20E8C, 0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180, 0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484,
0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9, 0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD, 0xB9980012,
0xA0833153, 0x8BAE6290, 0x92B553D1, 0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5, 0xAE07BCE9, 0xB71C8DA8,
0x9C31DE6B, 0x852AEF2A, 0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E, 0x66DE36E1, 0x7FC507A0, 0x54E85463,
0x4DF36522, 0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026, 0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B,
0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F, 0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773, 0x4870E1B4,
0x516BD0F5, 0x7A468336, 0x635DB277, 0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D, 0xAF96124A, 0xB68D230B,
0x9DA070C8, 0x84BB4189, 0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85, 0x674F9842, 0x7E54A903, 0x5579FAC0,
0x4C62CB81, 0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC, 0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8,
0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4, 0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0, 0x5E7EF3EC,
0x4765C2AD, 0x6C48916E, 0x7553A02F, 0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B, 0x96A779E4, 0x8FBC48A5,
0xA4911B66, 0xBD8A2A27, 0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23, 0x14BCE1BD, 0x0DA7D0FC, 0x268A833F,
0x3F91B27E, 0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A, 0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876,
0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72
},
new uint[]
{
0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59, 0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685, 0x0E1351B8,
0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1, 0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D, 0x1C26A370, 0x1DE4C947,
0x1FA2771E, 0x1E601D29, 0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5, 0x1235F2C8, 0x13F798FF, 0x11B126A6,
0x10734C91, 0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D, 0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9,
0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065, 0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901, 0x3157BF84,
0x3095D5B3, 0x32D36BEA, 0x331101DD, 0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9, 0x23624D4C, 0x22A0277B,
0x20E69922, 0x2124F315, 0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71, 0x2D711CF4, 0x2CB376C3, 0x2EF5C89A,
0x2F37A2AD, 0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399, 0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45,
0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221, 0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD, 0x6CBC2EB0,
0x6D7E4487, 0x6F38FADE, 0x6EFA90E9, 0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835, 0x62AF7F08, 0x636D153F,
0x612BAB66, 0x60E9C151, 0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D, 0x48D7CB20, 0x4915A117, 0x4B531F4E,
0x4A917579, 0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5, 0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1,
0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D, 0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609, 0x53F8C08C,
0x523AAABB, 0x507C14E2, 0x51BE7ED5, 0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1, 0x5DEB9134, 0x5C29FB03,
0x5E6F455A, 0x5FAD2F6D, 0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9, 0xE63CB35C, 0xE7FED96B, 0xE5B86732,
0xE47A0D05, 0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461, 0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD,
0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9, 0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75, 0xF300E948,
0xF2C2837F, 0xF0843D26, 0xF1465711, 0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD, 0xD9785D60, 0xD8BA3757,
0xDAFC890E, 0xDB3EE339, 0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5, 0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6,
0xD52DB281, 0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D, 0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049,
0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895, 0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1, 0xCC440774,
0xCD866D43, 0xCFC0D31A, 0xCE02B92D, 0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819, 0x96A63E9C, 0x976454AB,
0x9522EAF2, 0x94E080C5, 0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1, 0x98B56F24, 0x99770513, 0x9B31BB4A,
0x9AF3D17D, 0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69, 0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5,
0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1, 0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D, 0xA9E2D0A0,
0xA820BA97, 0xAA6604CE, 0xABA46EF9, 0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625, 0xA7F18118, 0xA633EB2F,
0xA4755576, 0xA5B73F41, 0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D, 0xB5C473D0, 0xB40619E7, 0xB640A7BE,
0xB782CD89, 0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555, 0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31,
0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED
},
new uint[]
{
0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE, 0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9, 0xC5B428EF,
0x7D084F8A, 0x6FBDE064, 0xD7018701, 0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056, 0x5019579F, 0xE8A530FA,
0xFA109F14, 0x42ACF871, 0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26, 0x95AD7F70, 0x2D111815, 0x3FA4B7FB,
0x8718D09E, 0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9, 0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0,
0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787, 0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F, 0xEAE41086,
0x525877E3, 0x40EDD80D, 0xF851BF68, 0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F, 0x7F496FF6, 0xC7F50893,
0xD540A77D, 0x6DFCC018, 0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0, 0xBAFD4719, 0x0241207C, 0x10F48F92,
0xA848E8F7, 0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3, 0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084,
0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C, 0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B, 0xCB0D0FA2,
0x73B168C7, 0x6104C729, 0xD9B8A04C, 0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B, 0x0EB9274D, 0xB6054028,
0xA4B0EFC6, 0x1C0C88A3, 0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4, 0x3B26F703, 0x839A9066, 0x912F3F88,
0x299358ED, 0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA, 0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002,
0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755, 0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72, 0xE45D37CB,
0x5CE150AE, 0x4E54FF40, 0xF6E89825, 0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D, 0x21E91F24, 0x99557841,
0x8BE0D7AF, 0x335CB0CA, 0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5, 0x623B216C, 0xDA874609, 0xC832E9E7,
0x708E8E82, 0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A, 0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D,
0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A, 0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D, 0x78F4C94B,
0xC048AE2E, 0xD2FD01C0, 0x6A4166A5, 0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2, 0x4D6B1905, 0xF5D77E60,
0xE762D18E, 0x5FDEB6EB, 0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC, 0x88DF31EA, 0x3063568F, 0x22D6F961,
0x9A6A9E04, 0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953, 0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174,
0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623, 0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B, 0x57A4F122,
0xEF189647, 0xFDAD39A9, 0x45115ECC, 0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8, 0xF92F7951, 0x41931E34,
0x5326B1DA, 0xEB9AD6BF, 0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907, 0x3C9B51BE, 0x842736DB, 0x96929935,
0x2E2EFE50, 0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677, 0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120,
0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98, 0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF, 0xD67F4138,
0x6EC3265D, 0x7C7689B3, 0xC4CAEED6, 0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981, 0x13CB69D7, 0xAB770EB2,
0xB9C2A15C, 0x017EC639, 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E, 0x866616A7, 0x3EDA71C2, 0x2C6FDE2C,
0x94D3B949, 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E, 0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6,
0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1
},
new uint[]
{
0x00000000, 0x3D6029B0, 0x7AC05360, 0x47A07AD0, 0xF580A6C0, 0xC8E08F70, 0x8F40F5A0, 0xB220DC10, 0x30704BC1,
0x0D106271, 0x4AB018A1, 0x77D03111, 0xC5F0ED01, 0xF890C4B1, 0xBF30BE61, 0x825097D1, 0x60E09782, 0x5D80BE32,
0x1A20C4E2, 0x2740ED52, 0x95603142, 0xA80018F2, 0xEFA06222, 0xD2C04B92, 0x5090DC43, 0x6DF0F5F3, 0x2A508F23,
0x1730A693, 0xA5107A83, 0x98705333, 0xDFD029E3, 0xE2B00053, 0xC1C12F04, 0xFCA106B4, 0xBB017C64, 0x866155D4,
0x344189C4, 0x0921A074, 0x4E81DAA4, 0x73E1F314, 0xF1B164C5, 0xCCD14D75, 0x8B7137A5, 0xB6111E15, 0x0431C205,
0x3951EBB5, 0x7EF19165, 0x4391B8D5, 0xA121B886, 0x9C419136, 0xDBE1EBE6, 0xE681C256, 0x54A11E46, 0x69C137F6,
0x2E614D26, 0x13016496, 0x9151F347, 0xAC31DAF7, 0xEB91A027, 0xD6F18997, 0x64D15587, 0x59B17C37, 0x1E1106E7,
0x23712F57, 0x58F35849, 0x659371F9, 0x22330B29, 0x1F532299, 0xAD73FE89, 0x9013D739, 0xD7B3ADE9, 0xEAD38459,
0x68831388, 0x55E33A38, 0x124340E8, 0x2F236958, 0x9D03B548, 0xA0639CF8, 0xE7C3E628, 0xDAA3CF98, 0x3813CFCB,
0x0573E67B, 0x42D39CAB, 0x7FB3B51B, 0xCD93690B, 0xF0F340BB, 0xB7533A6B, 0x8A3313DB, 0x0863840A, 0x3503ADBA,
0x72A3D76A, 0x4FC3FEDA, 0xFDE322CA, 0xC0830B7A, 0x872371AA, 0xBA43581A, 0x9932774D, 0xA4525EFD, 0xE3F2242D,
0xDE920D9D, 0x6CB2D18D, 0x51D2F83D, 0x167282ED, 0x2B12AB5D, 0xA9423C8C, 0x9422153C, 0xD3826FEC, 0xEEE2465C,
0x5CC29A4C, 0x61A2B3FC, 0x2602C92C, 0x1B62E09C, 0xF9D2E0CF, 0xC4B2C97F, 0x8312B3AF, 0xBE729A1F, 0x0C52460F,
0x31326FBF, 0x7692156F, 0x4BF23CDF, 0xC9A2AB0E, 0xF4C282BE, 0xB362F86E, 0x8E02D1DE, 0x3C220DCE, 0x0142247E,
0x46E25EAE, 0x7B82771E, 0xB1E6B092, 0x8C869922, 0xCB26E3F2, 0xF646CA42, 0x44661652, 0x79063FE2, 0x3EA64532,
0x03C66C82, 0x8196FB53, 0xBCF6D2E3, 0xFB56A833, 0xC6368183, 0x74165D93, 0x49767423, 0x0ED60EF3, 0x33B62743,
0xD1062710, 0xEC660EA0, 0xABC67470, 0x96A65DC0, 0x248681D0, 0x19E6A860, 0x5E46D2B0, 0x6326FB00, 0xE1766CD1,
0xDC164561, 0x9BB63FB1, 0xA6D61601, 0x14F6CA11, 0x2996E3A1, 0x6E369971, 0x5356B0C1, 0x70279F96, 0x4D47B626,
0x0AE7CCF6, 0x3787E546, 0x85A73956, 0xB8C710E6, 0xFF676A36, 0xC2074386, 0x4057D457, 0x7D37FDE7, 0x3A978737,
0x07F7AE87, 0xB5D77297, 0x88B75B27, 0xCF1721F7, 0xF2770847, 0x10C70814, 0x2DA721A4, 0x6A075B74, 0x576772C4,
0xE547AED4, 0xD8278764, 0x9F87FDB4, 0xA2E7D404, 0x20B743D5, 0x1DD76A65, 0x5A7710B5, 0x67173905, 0xD537E515,
0xE857CCA5, 0xAFF7B675, 0x92979FC5, 0xE915E8DB, 0xD475C16B, 0x93D5BBBB, 0xAEB5920B, 0x1C954E1B, 0x21F567AB,
0x66551D7B, 0x5B3534CB, 0xD965A31A, 0xE4058AAA, 0xA3A5F07A, 0x9EC5D9CA, 0x2CE505DA, 0x11852C6A, 0x562556BA,
0x6B457F0A, 0x89F57F59, 0xB49556E9, 0xF3352C39, 0xCE550589, 0x7C75D999, 0x4115F029, 0x06B58AF9, 0x3BD5A349,
0xB9853498, 0x84E51D28, 0xC34567F8, 0xFE254E48, 0x4C059258, 0x7165BBE8, 0x36C5C138, 0x0BA5E888, 0x28D4C7DF,
0x15B4EE6F, 0x521494BF, 0x6F74BD0F, 0xDD54611F, 0xE03448AF, 0xA794327F, 0x9AF41BCF, 0x18A48C1E, 0x25C4A5AE,
0x6264DF7E, 0x5F04F6CE, 0xED242ADE, 0xD044036E, 0x97E479BE, 0xAA84500E, 0x4834505D, 0x755479ED, 0x32F4033D,
0x0F942A8D, 0xBDB4F69D, 0x80D4DF2D, 0xC774A5FD, 0xFA148C4D, 0x78441B9C, 0x4524322C, 0x028448FC, 0x3FE4614C,
0x8DC4BD5C, 0xB0A494EC, 0xF704EE3C, 0xCA64C78C
},
new uint[]
{
0x00000000, 0xCB5CD3A5, 0x4DC8A10B, 0x869472AE, 0x9B914216, 0x50CD91B3, 0xD659E31D, 0x1D0530B8, 0xEC53826D,
0x270F51C8, 0xA19B2366, 0x6AC7F0C3, 0x77C2C07B, 0xBC9E13DE, 0x3A0A6170, 0xF156B2D5, 0x03D6029B, 0xC88AD13E,
0x4E1EA390, 0x85427035, 0x9847408D, 0x531B9328, 0xD58FE186, 0x1ED33223, 0xEF8580F6, 0x24D95353, 0xA24D21FD,
0x6911F258, 0x7414C2E0, 0xBF481145, 0x39DC63EB, 0xF280B04E, 0x07AC0536, 0xCCF0D693, 0x4A64A43D, 0x81387798,
0x9C3D4720, 0x57619485, 0xD1F5E62B, 0x1AA9358E, 0xEBFF875B, 0x20A354FE, 0xA6372650, 0x6D6BF5F5, 0x706EC54D,
0xBB3216E8, 0x3DA66446, 0xF6FAB7E3, 0x047A07AD, 0xCF26D408, 0x49B2A6A6, 0x82EE7503, 0x9FEB45BB, 0x54B7961E,
0xD223E4B0, 0x197F3715, 0xE82985C0, 0x23755665, 0xA5E124CB, 0x6EBDF76E, 0x73B8C7D6, 0xB8E41473, 0x3E7066DD,
0xF52CB578, 0x0F580A6C, 0xC404D9C9, 0x4290AB67, 0x89CC78C2, 0x94C9487A, 0x5F959BDF, 0xD901E971, 0x125D3AD4,
0xE30B8801, 0x28575BA4, 0xAEC3290A, 0x659FFAAF, 0x789ACA17, 0xB3C619B2, 0x35526B1C, 0xFE0EB8B9, 0x0C8E08F7,
0xC7D2DB52, 0x4146A9FC, 0x8A1A7A59, 0x971F4AE1, 0x5C439944, 0xDAD7EBEA, 0x118B384F, 0xE0DD8A9A, 0x2B81593F,
0xAD152B91, 0x6649F834, 0x7B4CC88C, 0xB0101B29, 0x36846987, 0xFDD8BA22, 0x08F40F5A, 0xC3A8DCFF, 0x453CAE51,
0x8E607DF4, 0x93654D4C, 0x58399EE9, 0xDEADEC47, 0x15F13FE2, 0xE4A78D37, 0x2FFB5E92, 0xA96F2C3C, 0x6233FF99,
0x7F36CF21, 0xB46A1C84, 0x32FE6E2A, 0xF9A2BD8F, 0x0B220DC1, 0xC07EDE64, 0x46EAACCA, 0x8DB67F6F, 0x90B34FD7,
0x5BEF9C72, 0xDD7BEEDC, 0x16273D79, 0xE7718FAC, 0x2C2D5C09, 0xAAB92EA7, 0x61E5FD02, 0x7CE0CDBA, 0xB7BC1E1F,
0x31286CB1, 0xFA74BF14, 0x1EB014D8, 0xD5ECC77D, 0x5378B5D3, 0x98246676, 0x852156CE, 0x4E7D856B, 0xC8E9F7C5,
0x03B52460, 0xF2E396B5, 0x39BF4510, 0xBF2B37BE, 0x7477E41B, 0x6972D4A3, 0xA22E0706, 0x24BA75A8, 0xEFE6A60D,
0x1D661643, 0xD63AC5E6, 0x50AEB748, 0x9BF264ED, 0x86F75455, 0x4DAB87F0, 0xCB3FF55E, 0x006326FB, 0xF135942E,
0x3A69478B, 0xBCFD3525, 0x77A1E680, 0x6AA4D638, 0xA1F8059D, 0x276C7733, 0xEC30A496, 0x191C11EE, 0xD240C24B,
0x54D4B0E5, 0x9F886340, 0x828D53F8, 0x49D1805D, 0xCF45F2F3, 0x04192156, 0xF54F9383, 0x3E134026, 0xB8873288,
0x73DBE12D, 0x6EDED195, 0xA5820230, 0x2316709E, 0xE84AA33B, 0x1ACA1375, 0xD196C0D0, 0x5702B27E, 0x9C5E61DB,
0x815B5163, 0x4A0782C6, 0xCC93F068, 0x07CF23CD, 0xF6999118, 0x3DC542BD, 0xBB513013, 0x700DE3B6, 0x6D08D30E,
0xA65400AB, 0x20C07205, 0xEB9CA1A0, 0x11E81EB4, 0xDAB4CD11, 0x5C20BFBF, 0x977C6C1A, 0x8A795CA2, 0x41258F07,
0xC7B1FDA9, 0x0CED2E0C, 0xFDBB9CD9, 0x36E74F7C, 0xB0733DD2, 0x7B2FEE77, 0x662ADECF, 0xAD760D6A, 0x2BE27FC4,
0xE0BEAC61, 0x123E1C2F, 0xD962CF8A, 0x5FF6BD24, 0x94AA6E81, 0x89AF5E39, 0x42F38D9C, 0xC467FF32, 0x0F3B2C97,
0xFE6D9E42, 0x35314DE7, 0xB3A53F49, 0x78F9ECEC, 0x65FCDC54, 0xAEA00FF1, 0x28347D5F, 0xE368AEFA, 0x16441B82,
0xDD18C827, 0x5B8CBA89, 0x90D0692C, 0x8DD55994, 0x46898A31, 0xC01DF89F, 0x0B412B3A, 0xFA1799EF, 0x314B4A4A,
0xB7DF38E4, 0x7C83EB41, 0x6186DBF9, 0xAADA085C, 0x2C4E7AF2, 0xE712A957, 0x15921919, 0xDECECABC, 0x585AB812,
0x93066BB7, 0x8E035B0F, 0x455F88AA, 0xC3CBFA04, 0x089729A1, 0xF9C19B74, 0x329D48D1, 0xB4093A7F, 0x7F55E9DA,
0x6250D962, 0xA90C0AC7, 0x2F987869, 0xE4C4ABCC
},
new uint[]
{
0x00000000, 0xA6770BB4, 0x979F1129, 0x31E81A9D, 0xF44F2413, 0x52382FA7, 0x63D0353A, 0xC5A73E8E, 0x33EF4E67,
0x959845D3, 0xA4705F4E, 0x020754FA, 0xC7A06A74, 0x61D761C0, 0x503F7B5D, 0xF64870E9, 0x67DE9CCE, 0xC1A9977A,
0xF0418DE7, 0x56368653, 0x9391B8DD, 0x35E6B369, 0x040EA9F4, 0xA279A240, 0x5431D2A9, 0xF246D91D, 0xC3AEC380,
0x65D9C834, 0xA07EF6BA, 0x0609FD0E, 0x37E1E793, 0x9196EC27, 0xCFBD399C, 0x69CA3228, 0x582228B5, 0xFE552301,
0x3BF21D8F, 0x9D85163B, 0xAC6D0CA6, 0x0A1A0712, 0xFC5277FB, 0x5A257C4F, 0x6BCD66D2, 0xCDBA6D66, 0x081D53E8,
0xAE6A585C, 0x9F8242C1, 0x39F54975, 0xA863A552, 0x0E14AEE6, 0x3FFCB47B, 0x998BBFCF, 0x5C2C8141, 0xFA5B8AF5,
0xCBB39068, 0x6DC49BDC, 0x9B8CEB35, 0x3DFBE081, 0x0C13FA1C, 0xAA64F1A8, 0x6FC3CF26, 0xC9B4C492, 0xF85CDE0F,
0x5E2BD5BB, 0x440B7579, 0xE27C7ECD, 0xD3946450, 0x75E36FE4, 0xB044516A, 0x16335ADE, 0x27DB4043, 0x81AC4BF7,
0x77E43B1E, 0xD19330AA, 0xE07B2A37, 0x460C2183, 0x83AB1F0D, 0x25DC14B9, 0x14340E24, 0xB2430590, 0x23D5E9B7,
0x85A2E203, 0xB44AF89E, 0x123DF32A, 0xD79ACDA4, 0x71EDC610, 0x4005DC8D, 0xE672D739, 0x103AA7D0, 0xB64DAC64,
0x87A5B6F9, 0x21D2BD4D, 0xE47583C3, 0x42028877, 0x73EA92EA, 0xD59D995E, 0x8BB64CE5, 0x2DC14751, 0x1C295DCC,
0xBA5E5678, 0x7FF968F6, 0xD98E6342, 0xE86679DF, 0x4E11726B, 0xB8590282, 0x1E2E0936, 0x2FC613AB, 0x89B1181F,
0x4C162691, 0xEA612D25, 0xDB8937B8, 0x7DFE3C0C, 0xEC68D02B, 0x4A1FDB9F, 0x7BF7C102, 0xDD80CAB6, 0x1827F438,
0xBE50FF8C, 0x8FB8E511, 0x29CFEEA5, 0xDF879E4C, 0x79F095F8, 0x48188F65, 0xEE6F84D1, 0x2BC8BA5F, 0x8DBFB1EB,
0xBC57AB76, 0x1A20A0C2, 0x8816EAF2, 0x2E61E146, 0x1F89FBDB, 0xB9FEF06F, 0x7C59CEE1, 0xDA2EC555, 0xEBC6DFC8,
0x4DB1D47C, 0xBBF9A495, 0x1D8EAF21, 0x2C66B5BC, 0x8A11BE08, 0x4FB68086, 0xE9C18B32, 0xD82991AF, 0x7E5E9A1B,
0xEFC8763C, 0x49BF7D88, 0x78576715, 0xDE206CA1, 0x1B87522F, 0xBDF0599B, 0x8C184306, 0x2A6F48B2, 0xDC27385B,
0x7A5033EF, 0x4BB82972, 0xEDCF22C6, 0x28681C48, 0x8E1F17FC, 0xBFF70D61, 0x198006D5, 0x47ABD36E, 0xE1DCD8DA,
0xD034C247, 0x7643C9F3, 0xB3E4F77D, 0x1593FCC9, 0x247BE654, 0x820CEDE0, 0x74449D09, 0xD23396BD, 0xE3DB8C20,
0x45AC8794, 0x800BB91A, 0x267CB2AE, 0x1794A833, 0xB1E3A387, 0x20754FA0, 0x86024414, 0xB7EA5E89, 0x119D553D,
0xD43A6BB3, 0x724D6007, 0x43A57A9A, 0xE5D2712E, 0x139A01C7, 0xB5ED0A73, 0x840510EE, 0x22721B5A, 0xE7D525D4,
0x41A22E60, 0x704A34FD, 0xD63D3F49, 0xCC1D9F8B, 0x6A6A943F, 0x5B828EA2, 0xFDF58516, 0x3852BB98, 0x9E25B02C,
0xAFCDAAB1, 0x09BAA105, 0xFFF2D1EC, 0x5985DA58, 0x686DC0C5, 0xCE1ACB71, 0x0BBDF5FF, 0xADCAFE4B, 0x9C22E4D6,
0x3A55EF62, 0xABC30345, 0x0DB408F1, 0x3C5C126C, 0x9A2B19D8, 0x5F8C2756, 0xF9FB2CE2, 0xC813367F, 0x6E643DCB,
0x982C4D22, 0x3E5B4696, 0x0FB35C0B, 0xA9C457BF, 0x6C636931, 0xCA146285, 0xFBFC7818, 0x5D8B73AC, 0x03A0A617,
0xA5D7ADA3, 0x943FB73E, 0x3248BC8A, 0xF7EF8204, 0x519889B0, 0x6070932D, 0xC6079899, 0x304FE870, 0x9638E3C4,
0xA7D0F959, 0x01A7F2ED, 0xC400CC63, 0x6277C7D7, 0x539FDD4A, 0xF5E8D6FE, 0x647E3AD9, 0xC209316D, 0xF3E12BF0,
0x55962044, 0x90311ECA, 0x3646157E, 0x07AE0FE3, 0xA1D90457, 0x579174BE, 0xF1E67F0A, 0xC00E6597, 0x66796E23,
0xA3DE50AD, 0x05A95B19, 0x34414184, 0x92364A30
},
new uint[]
{
0x00000000, 0xCCAA009E, 0x4225077D, 0x8E8F07E3, 0x844A0EFA, 0x48E00E64, 0xC66F0987, 0x0AC50919, 0xD3E51BB5,
0x1F4F1B2B, 0x91C01CC8, 0x5D6A1C56, 0x57AF154F, 0x9B0515D1, 0x158A1232, 0xD92012AC, 0x7CBB312B, 0xB01131B5,
0x3E9E3656, 0xF23436C8, 0xF8F13FD1, 0x345B3F4F, 0xBAD438AC, 0x767E3832, 0xAF5E2A9E, 0x63F42A00, 0xED7B2DE3,
0x21D12D7D, 0x2B142464, 0xE7BE24FA, 0x69312319, 0xA59B2387, 0xF9766256, 0x35DC62C8, 0xBB53652B, 0x77F965B5,
0x7D3C6CAC, 0xB1966C32, 0x3F196BD1, 0xF3B36B4F, 0x2A9379E3, 0xE639797D, 0x68B67E9E, 0xA41C7E00, 0xAED97719,
0x62737787, 0xECFC7064, 0x205670FA, 0x85CD537D, 0x496753E3, 0xC7E85400, 0x0B42549E, 0x01875D87, 0xCD2D5D19,
0x43A25AFA, 0x8F085A64, 0x562848C8, 0x9A824856, 0x140D4FB5, 0xD8A74F2B, 0xD2624632, 0x1EC846AC, 0x9047414F,
0x5CED41D1, 0x299DC2ED, 0xE537C273, 0x6BB8C590, 0xA712C50E, 0xADD7CC17, 0x617DCC89, 0xEFF2CB6A, 0x2358CBF4,
0xFA78D958, 0x36D2D9C6, 0xB85DDE25, 0x74F7DEBB, 0x7E32D7A2, 0xB298D73C, 0x3C17D0DF, 0xF0BDD041, 0x5526F3C6,
0x998CF358, 0x1703F4BB, 0xDBA9F425, 0xD16CFD3C, 0x1DC6FDA2, 0x9349FA41, 0x5FE3FADF, 0x86C3E873, 0x4A69E8ED,
0xC4E6EF0E, 0x084CEF90, 0x0289E689, 0xCE23E617, 0x40ACE1F4, 0x8C06E16A, 0xD0EBA0BB, 0x1C41A025, 0x92CEA7C6,
0x5E64A758, 0x54A1AE41, 0x980BAEDF, 0x1684A93C, 0xDA2EA9A2, 0x030EBB0E, 0xCFA4BB90, 0x412BBC73, 0x8D81BCED,
0x8744B5F4, 0x4BEEB56A, 0xC561B289, 0x09CBB217, 0xAC509190, 0x60FA910E, 0xEE7596ED, 0x22DF9673, 0x281A9F6A,
0xE4B09FF4, 0x6A3F9817, 0xA6959889, 0x7FB58A25, 0xB31F8ABB, 0x3D908D58, 0xF13A8DC6, 0xFBFF84DF, 0x37558441,
0xB9DA83A2, 0x7570833C, 0x533B85DA, 0x9F918544, 0x111E82A7, 0xDDB48239, 0xD7718B20, 0x1BDB8BBE, 0x95548C5D,
0x59FE8CC3, 0x80DE9E6F, 0x4C749EF1, 0xC2FB9912, 0x0E51998C, 0x04949095, 0xC83E900B, 0x46B197E8, 0x8A1B9776,
0x2F80B4F1, 0xE32AB46F, 0x6DA5B38C, 0xA10FB312, 0xABCABA0B, 0x6760BA95, 0xE9EFBD76, 0x2545BDE8, 0xFC65AF44,
0x30CFAFDA, 0xBE40A839, 0x72EAA8A7, 0x782FA1BE, 0xB485A120, 0x3A0AA6C3, 0xF6A0A65D, 0xAA4DE78C, 0x66E7E712,
0xE868E0F1, 0x24C2E06F, 0x2E07E976, 0xE2ADE9E8, 0x6C22EE0B, 0xA088EE95, 0x79A8FC39, 0xB502FCA7, 0x3B8DFB44,
0xF727FBDA, 0xFDE2F2C3, 0x3148F25D, 0xBFC7F5BE, 0x736DF520, 0xD6F6D6A7, 0x1A5CD639, 0x94D3D1DA, 0x5879D144,
0x52BCD85D, 0x9E16D8C3, 0x1099DF20, 0xDC33DFBE, 0x0513CD12, 0xC9B9CD8C, 0x4736CA6F, 0x8B9CCAF1, 0x8159C3E8,
0x4DF3C376, 0xC37CC495, 0x0FD6C40B, 0x7AA64737, 0xB60C47A9, 0x3883404A, 0xF42940D4, 0xFEEC49CD, 0x32464953,
0xBCC94EB0, 0x70634E2E, 0xA9435C82, 0x65E95C1C, 0xEB665BFF, 0x27CC5B61, 0x2D095278, 0xE1A352E6, 0x6F2C5505,
0xA386559B, 0x061D761C, 0xCAB77682, 0x44387161, 0x889271FF, 0x825778E6, 0x4EFD7878, 0xC0727F9B, 0x0CD87F05,
0xD5F86DA9, 0x19526D37, 0x97DD6AD4, 0x5B776A4A, 0x51B26353, 0x9D1863CD, 0x1397642E, 0xDF3D64B0, 0x83D02561,
0x4F7A25FF, 0xC1F5221C, 0x0D5F2282, 0x079A2B9B, 0xCB302B05, 0x45BF2CE6, 0x89152C78, 0x50353ED4, 0x9C9F3E4A,
0x121039A9, 0xDEBA3937, 0xD47F302E, 0x18D530B0, 0x965A3753, 0x5AF037CD, 0xFF6B144A, 0x33C114D4, 0xBD4E1337,
0x71E413A9, 0x7B211AB0, 0xB78B1A2E, 0x39041DCD, 0xF5AE1D53, 0x2C8E0FFF, 0xE0240F61, 0x6EAB0882, 0xA201081C,
0xA8C40105, 0x646E019B, 0xEAE10678, 0x264B06E6
}
};
readonly uint _finalSeed;
readonly IntPtr _nativeContext;
readonly uint[][]? _table;
readonly bool _useIso;
readonly bool _useNative;
uint _hashInt;
/// <summary>Initializes the CRC32 table and seed as CRC32-ISO</summary>
public Crc32Context()
{
_hashInt = CRC32_ISO_SEED;
_finalSeed = CRC32_ISO_SEED;
_table = ISOCrc32Table;
_useIso = true;
if(!Native.IsSupported)
return;
_nativeContext = crc32_init();
_useNative = _nativeContext != IntPtr.Zero;
}
/// <summary>Initializes the CRC32 table with a custom polynomial and seed</summary>
public Crc32Context(uint polynomial, uint seed)
{
_hashInt = seed;
_finalSeed = seed;
_useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
if(Native.IsSupported && _useIso)
{
_nativeContext = crc32_init();
_useNative = _nativeContext != IntPtr.Zero;
}
else
_table = GenerateTable(polynomial);
}
#region IChecksum Members
/// <inheritdoc />
public string Name => "CRC-32";
/// <inheritdoc />
public Guid Id => new("BCC4E18A-79CD-4B52-8A57-2B599E5176B3");
/// <inheritdoc />
public string Author => "Natalia Portillo";
/// <inheritdoc />
/// <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) =>
Step(ref _hashInt, _table!, data, len, _useIso, _useNative, _nativeContext);
/// <inheritdoc />
/// <summary>Updates the hash with data.</summary>
/// <param name="data">Data buffer.</param>
public void Update(byte[] data) => Update(data, (uint)data.Length);
/// <inheritdoc />
/// <summary>Returns a byte array of the hash value.</summary>
public byte[] Final()
{
uint crc = _hashInt ^ _finalSeed;
if(!_useNative || !_useIso)
return BigEndianBitConverter.GetBytes(crc);
crc32_final(_nativeContext, ref crc);
crc32_free(_nativeContext);
return BigEndianBitConverter.GetBytes(crc);
}
/// <inheritdoc />
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
public string End()
{
uint crc = _hashInt ^ _finalSeed;
var crc32Output = new StringBuilder();
if(_useNative && _useIso)
{
crc32_final(_nativeContext, ref crc);
crc32_free(_nativeContext);
}
for(var i = 0; i < BigEndianBitConverter.GetBytes(crc).Length; i++)
crc32Output.Append(BigEndianBitConverter.GetBytes(crc)[i].ToString("x2"));
return crc32Output.ToString();
}
#endregion
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern IntPtr crc32_init();
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int crc32_update(IntPtr ctx, byte[] data, uint len);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int crc32_final(IntPtr ctx, ref uint crc);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern void crc32_free(IntPtr ctx);
static uint[][] GenerateTable(uint polynomial)
{
var table = new uint[8][];
for(var i = 0; i < 8; i++)
table[i] = new uint[256];
for(var i = 0; i < 256; i++)
{
var entry = (uint)i;
for(var j = 0; j < 8; j++)
{
if((entry & 1) == 1)
entry = entry >> 1 ^ polynomial;
else
entry >>= 1;
}
table[0][i] = entry;
}
for(var slice = 1; slice < 8; slice++)
for(var i = 0; i < 256; i++)
table[slice][i] = table[slice - 1][i] >> 8 ^ table[0][table[slice - 1][i] & 0xFF];
return table;
}
static void Step(ref uint previousCrc, uint[][] table, byte[] data, uint len, bool useIso, bool useNative,
IntPtr nativeContext)
{
if(useNative && useIso)
{
crc32_update(nativeContext, data, len);
return;
}
var currentPos = 0;
if(useIso)
{
#if NETCOREAPP3_1_OR_GREATER
if(Pclmulqdq.IsSupported && Sse41.IsSupported && Ssse3.IsSupported && Sse2.IsSupported)
{
// Only works in blocks of 16 bytes
uint blocks = len / 64;
if(blocks > 0)
{
previousCrc = ~Clmul.Step(data, blocks * 64, ~previousCrc);
currentPos = (int)(blocks * 64);
len -= blocks * 64;
}
if(len == 0)
return;
}
#endif
#if NET5_0_OR_GREATER
if(Crc32.Arm64.IsSupported)
{
previousCrc = ArmSimd.Step64(data, len, previousCrc);
return;
}
if(Crc32.IsSupported)
{
previousCrc = ArmSimd.Step32(data, len, previousCrc);
return;
}
#endif
}
// Unroll according to Intel slicing by uint8_t
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
// http://sourceforge.net/projects/slicing-by-8/
const int unroll = 4;
const int bytesAtOnce = 8 * unroll;
uint crc = previousCrc;
while(len >= bytesAtOnce)
{
int unrolling;
for(unrolling = 0; unrolling < unroll; unrolling++)
{
uint one = BitConverter.ToUInt32(data, currentPos) ^ crc;
currentPos += 4;
var two = BitConverter.ToUInt32(data, currentPos);
currentPos += 4;
crc = table[0][two >> 24 & 0xFF] ^
table[1][two >> 16 & 0xFF] ^
table[2][two >> 8 & 0xFF] ^
table[3][two & 0xFF] ^
table[4][one >> 24 & 0xFF] ^
table[5][one >> 16 & 0xFF] ^
table[6][one >> 8 & 0xFF] ^
table[7][one & 0xFF];
}
len -= bytesAtOnce;
}
while(len-- != 0)
crc = crc >> 8 ^ table[0][crc & 0xFF ^ data[currentPos++]];
previousCrc = crc;
}
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
public static byte[] File(string filename)
{
File(filename, out byte[] hash);
return hash;
}
/// <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) =>
File(filename, out hash, CRC32_ISO_POLY, CRC32_ISO_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>
/// <param name="polynomial">CRC polynomial</param>
/// <param name="seed">CRC seed</param>
public static string File(string filename, out byte[] hash, uint polynomial, uint seed)
{
bool useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
bool useNative = Native.IsSupported;
IntPtr nativeContext = IntPtr.Zero;
if(useNative && useIso)
{
nativeContext = crc32_init();
useNative = nativeContext != IntPtr.Zero;
}
var fileStream = new FileStream(filename, FileMode.Open);
uint localHashInt = seed;
uint[][] localTable = GenerateTable(polynomial);
var buffer = new byte[65536];
int read = fileStream.EnsureRead(buffer, 0, 65536);
while(read > 0)
{
Step(ref localHashInt, localTable, buffer, (uint)read, useIso, useNative, nativeContext);
read = fileStream.EnsureRead(buffer, 0, 65536);
}
localHashInt ^= seed;
if(useNative && useIso)
{
crc32_final(nativeContext, ref localHashInt);
crc32_free(nativeContext);
}
hash = BigEndianBitConverter.GetBytes(localHashInt);
var crc32Output = new StringBuilder();
foreach(byte h in hash)
crc32Output.Append(h.ToString("x2"));
fileStream.Close();
return crc32Output.ToString();
}
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of the data buffer to hash.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, uint len, out byte[] hash) =>
Data(data, len, out hash, CRC32_ISO_POLY, CRC32_ISO_SEED);
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of the data buffer to hash.</param>
/// <param name="hash">Byte array of the hash value.</param>
/// <param name="polynomial">CRC polynomial</param>
/// <param name="seed">CRC seed</param>
public static string Data(byte[] data, uint len, out byte[] hash, uint polynomial, uint seed)
{
bool useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
bool useNative = Native.IsSupported;
IntPtr nativeContext = IntPtr.Zero;
if(useNative && useIso)
{
nativeContext = crc32_init();
useNative = nativeContext != IntPtr.Zero;
}
uint localHashInt = seed;
uint[][] localTable = GenerateTable(polynomial);
Step(ref localHashInt, localTable, data, len, useIso, useNative, nativeContext);
localHashInt ^= seed;
if(useNative && useIso)
{
crc32_final(nativeContext, ref localHashInt);
crc32_free(nativeContext);
}
hash = BigEndianBitConverter.GetBytes(localHashInt);
var crc32Output = new StringBuilder();
foreach(byte h in hash)
crc32Output.Append(h.ToString("x2"));
return crc32Output.ToString();
}
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
}

View File

@@ -1,111 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : clmul.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Compute the CRC64 using a parallelized folding approach with the PCLMULQDQ
// instruction.
//
// --[ License ] --------------------------------------------------------------
//
// This file is under the public domain:
// https://github.com/rawrunprotected/crc
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
#if NETCOREAPP3_1_OR_GREATER
using System;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
namespace Aaru.Checksums.CRC64;
static class Clmul
{
static readonly byte[] _shuffleMasks =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x8f, 0x8e,
0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void ShiftRight128(Vector128<ulong> initial, uint n, out Vector128<ulong> outLeft,
out Vector128<ulong> outRight)
{
uint maskPos = 16 - n;
var maskA = Vector128.Create(_shuffleMasks[maskPos], _shuffleMasks[maskPos + 1], _shuffleMasks[maskPos + 2],
_shuffleMasks[maskPos + 3], _shuffleMasks[maskPos + 4], _shuffleMasks[maskPos + 5],
_shuffleMasks[maskPos + 6], _shuffleMasks[maskPos + 7], _shuffleMasks[maskPos + 8],
_shuffleMasks[maskPos + 9], _shuffleMasks[maskPos + 10],
_shuffleMasks[maskPos + 11], _shuffleMasks[maskPos + 12],
_shuffleMasks[maskPos + 13], _shuffleMasks[maskPos + 14],
_shuffleMasks[maskPos + 15]);
Vector128<byte> maskB = Sse2.Xor(maskA, Sse2.CompareEqual(Vector128<byte>.Zero, Vector128<byte>.Zero));
outLeft = Ssse3.Shuffle(initial.AsByte(), maskB).AsUInt64();
outRight = Ssse3.Shuffle(initial.AsByte(), maskA).AsUInt64();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static Vector128<ulong> Fold(Vector128<ulong> input, Vector128<ulong> foldConstants) =>
Sse2.Xor(Pclmulqdq.CarrylessMultiply(input, foldConstants, 0x00),
Pclmulqdq.CarrylessMultiply(input, foldConstants, 0x11));
internal static ulong Step(ulong crc, byte[] data, uint length)
{
var bufPos = 16;
const ulong k1 = 0xe05dd497ca393ae4;
const ulong k2 = 0xdabe95afc7875f40;
const ulong mu = 0x9c3e466c172963d5;
const ulong pol = 0x92d8af2baf0e1e85;
var foldConstants1 = Vector128.Create(k1, k2);
var foldConstants2 = Vector128.Create(mu, pol);
var initialCrc = Vector128.Create(~crc, 0);
length -= 16;
// Initial CRC can simply be added to data
ShiftRight128(initialCrc, 0, out Vector128<ulong> crc0, out Vector128<ulong> crc1);
Vector128<ulong> accumulator =
Sse2.Xor(Fold(Sse2.Xor(crc0, Vector128.Create(BitConverter.ToUInt64(data, 0), BitConverter.ToUInt64(data, 8))), foldConstants1),
crc1);
while(length >= 32)
{
accumulator =
Fold(Sse2.Xor(Vector128.Create(BitConverter.ToUInt64(data, bufPos), BitConverter.ToUInt64(data, bufPos + 8)), accumulator),
foldConstants1);
length -= 16;
bufPos += 16;
}
Vector128<ulong> p = Sse2.Xor(accumulator,
Vector128.Create(BitConverter.ToUInt64(data, bufPos),
BitConverter.ToUInt64(data, bufPos + 8)));
Vector128<ulong> r = Sse2.Xor(Pclmulqdq.CarrylessMultiply(p, foldConstants1, 0x10),
Sse2.ShiftRightLogical128BitLane(p, 8));
// Final Barrett reduction
Vector128<ulong> t1 = Pclmulqdq.CarrylessMultiply(r, foldConstants2, 0x00);
Vector128<ulong> t2 =
Sse2.Xor(Sse2.Xor(Pclmulqdq.CarrylessMultiply(t1, foldConstants2, 0x10), Sse2.ShiftLeftLogical128BitLane(t1, 8)),
r);
return ~((ulong)Sse41.Extract(t2.AsUInt32(), 3) << 32 | Sse41.Extract(t2.AsUInt32(), 2));
}
}
#endif

View File

@@ -1,608 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : CRC64Context.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Checksums.
//
// --[ Description ] ----------------------------------------------------------
//
// Implements a CRC64 algorithm.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
#if NETCOREAPP3_1_OR_GREATER
using System.Runtime.Intrinsics.X86;
#endif
using System.Text;
#if NETCOREAPP3_1_OR_GREATER
using Aaru.Checksums.CRC64;
#endif
using Aaru.CommonTypes.Interfaces;
using Aaru.Helpers;
namespace Aaru.Checksums;
/// <inheritdoc />
/// <summary>Implements a CRC64 algorithm</summary>
[SuppressMessage("ReSharper", "UnusedMember.Global")]
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
public sealed class Crc64Context : IChecksum
{
/// <summary>ECMA CRC64 polynomial</summary>
const ulong CRC64_ECMA_POLY = 0xC96C5795D7870F42;
/// <summary>ECMA CRC64 seed</summary>
const ulong CRC64_ECMA_SEED = 0xFFFFFFFFFFFFFFFF;
static readonly ulong[][] _ecmaCrc64Table =
{
new ulong[]
{
0x0000000000000000, 0xB32E4CBE03A75F6F, 0xF4843657A840A05B, 0x47AA7AE9ABE7FF34, 0x7BD0C384FF8F5E33,
0xC8FE8F3AFC28015C, 0x8F54F5D357CFFE68, 0x3C7AB96D5468A107, 0xF7A18709FF1EBC66, 0x448FCBB7FCB9E309,
0x0325B15E575E1C3D, 0xB00BFDE054F94352, 0x8C71448D0091E255, 0x3F5F08330336BD3A, 0x78F572DAA8D1420E,
0xCBDB3E64AB761D61, 0x7D9BA13851336649, 0xCEB5ED8652943926, 0x891F976FF973C612, 0x3A31DBD1FAD4997D,
0x064B62BCAEBC387A, 0xB5652E02AD1B6715, 0xF2CF54EB06FC9821, 0x41E11855055BC74E, 0x8A3A2631AE2DDA2F,
0x39146A8FAD8A8540, 0x7EBE1066066D7A74, 0xCD905CD805CA251B, 0xF1EAE5B551A2841C, 0x42C4A90B5205DB73,
0x056ED3E2F9E22447, 0xB6409F5CFA457B28, 0xFB374270A266CC92, 0x48190ECEA1C193FD, 0x0FB374270A266CC9,
0xBC9D3899098133A6, 0x80E781F45DE992A1, 0x33C9CD4A5E4ECDCE, 0x7463B7A3F5A932FA, 0xC74DFB1DF60E6D95,
0x0C96C5795D7870F4, 0xBFB889C75EDF2F9B, 0xF812F32EF538D0AF, 0x4B3CBF90F69F8FC0, 0x774606FDA2F72EC7,
0xC4684A43A15071A8, 0x83C230AA0AB78E9C, 0x30EC7C140910D1F3, 0x86ACE348F355AADB, 0x3582AFF6F0F2F5B4,
0x7228D51F5B150A80, 0xC10699A158B255EF, 0xFD7C20CC0CDAF4E8, 0x4E526C720F7DAB87, 0x09F8169BA49A54B3,
0xBAD65A25A73D0BDC, 0x710D64410C4B16BD, 0xC22328FF0FEC49D2, 0x85895216A40BB6E6, 0x36A71EA8A7ACE989,
0x0ADDA7C5F3C4488E, 0xB9F3EB7BF06317E1, 0xFE5991925B84E8D5, 0x4D77DD2C5823B7BA, 0x64B62BCAEBC387A1,
0xD7986774E864D8CE, 0x90321D9D438327FA, 0x231C512340247895, 0x1F66E84E144CD992, 0xAC48A4F017EB86FD,
0xEBE2DE19BC0C79C9, 0x58CC92A7BFAB26A6, 0x9317ACC314DD3BC7, 0x2039E07D177A64A8, 0x67939A94BC9D9B9C,
0xD4BDD62ABF3AC4F3, 0xE8C76F47EB5265F4, 0x5BE923F9E8F53A9B, 0x1C4359104312C5AF, 0xAF6D15AE40B59AC0,
0x192D8AF2BAF0E1E8, 0xAA03C64CB957BE87, 0xEDA9BCA512B041B3, 0x5E87F01B11171EDC, 0x62FD4976457FBFDB,
0xD1D305C846D8E0B4, 0x96797F21ED3F1F80, 0x2557339FEE9840EF, 0xEE8C0DFB45EE5D8E, 0x5DA24145464902E1,
0x1A083BACEDAEFDD5, 0xA9267712EE09A2BA, 0x955CCE7FBA6103BD, 0x267282C1B9C65CD2, 0x61D8F8281221A3E6,
0xD2F6B4961186FC89, 0x9F8169BA49A54B33, 0x2CAF25044A02145C, 0x6B055FEDE1E5EB68, 0xD82B1353E242B407,
0xE451AA3EB62A1500, 0x577FE680B58D4A6F, 0x10D59C691E6AB55B, 0xA3FBD0D71DCDEA34, 0x6820EEB3B6BBF755,
0xDB0EA20DB51CA83A, 0x9CA4D8E41EFB570E, 0x2F8A945A1D5C0861, 0x13F02D374934A966, 0xA0DE61894A93F609,
0xE7741B60E174093D, 0x545A57DEE2D35652, 0xE21AC88218962D7A, 0x5134843C1B317215, 0x169EFED5B0D68D21,
0xA5B0B26BB371D24E, 0x99CA0B06E7197349, 0x2AE447B8E4BE2C26, 0x6D4E3D514F59D312, 0xDE6071EF4CFE8C7D,
0x15BB4F8BE788911C, 0xA6950335E42FCE73, 0xE13F79DC4FC83147, 0x521135624C6F6E28, 0x6E6B8C0F1807CF2F,
0xDD45C0B11BA09040, 0x9AEFBA58B0476F74, 0x29C1F6E6B3E0301B, 0xC96C5795D7870F42, 0x7A421B2BD420502D,
0x3DE861C27FC7AF19, 0x8EC62D7C7C60F076, 0xB2BC941128085171, 0x0192D8AF2BAF0E1E, 0x4638A2468048F12A,
0xF516EEF883EFAE45, 0x3ECDD09C2899B324, 0x8DE39C222B3EEC4B, 0xCA49E6CB80D9137F, 0x7967AA75837E4C10,
0x451D1318D716ED17, 0xF6335FA6D4B1B278, 0xB199254F7F564D4C, 0x02B769F17CF11223, 0xB4F7F6AD86B4690B,
0x07D9BA1385133664, 0x4073C0FA2EF4C950, 0xF35D8C442D53963F, 0xCF273529793B3738, 0x7C0979977A9C6857,
0x3BA3037ED17B9763, 0x888D4FC0D2DCC80C, 0x435671A479AAD56D, 0xF0783D1A7A0D8A02, 0xB7D247F3D1EA7536,
0x04FC0B4DD24D2A59, 0x3886B22086258B5E, 0x8BA8FE9E8582D431, 0xCC0284772E652B05, 0x7F2CC8C92DC2746A,
0x325B15E575E1C3D0, 0x8175595B76469CBF, 0xC6DF23B2DDA1638B, 0x75F16F0CDE063CE4, 0x498BD6618A6E9DE3,
0xFAA59ADF89C9C28C, 0xBD0FE036222E3DB8, 0x0E21AC88218962D7, 0xC5FA92EC8AFF7FB6, 0x76D4DE52895820D9,
0x317EA4BB22BFDFED, 0x8250E80521188082, 0xBE2A516875702185, 0x0D041DD676D77EEA, 0x4AAE673FDD3081DE,
0xF9802B81DE97DEB1, 0x4FC0B4DD24D2A599, 0xFCEEF8632775FAF6, 0xBB44828A8C9205C2, 0x086ACE348F355AAD,
0x34107759DB5DFBAA, 0x873E3BE7D8FAA4C5, 0xC094410E731D5BF1, 0x73BA0DB070BA049E, 0xB86133D4DBCC19FF,
0x0B4F7F6AD86B4690, 0x4CE50583738CB9A4, 0xFFCB493D702BE6CB, 0xC3B1F050244347CC, 0x709FBCEE27E418A3,
0x3735C6078C03E797, 0x841B8AB98FA4B8F8, 0xADDA7C5F3C4488E3, 0x1EF430E13FE3D78C, 0x595E4A08940428B8,
0xEA7006B697A377D7, 0xD60ABFDBC3CBD6D0, 0x6524F365C06C89BF, 0x228E898C6B8B768B, 0x91A0C532682C29E4,
0x5A7BFB56C35A3485, 0xE955B7E8C0FD6BEA, 0xAEFFCD016B1A94DE, 0x1DD181BF68BDCBB1, 0x21AB38D23CD56AB6,
0x9285746C3F7235D9, 0xD52F0E859495CAED, 0x6601423B97329582, 0xD041DD676D77EEAA, 0x636F91D96ED0B1C5,
0x24C5EB30C5374EF1, 0x97EBA78EC690119E, 0xAB911EE392F8B099, 0x18BF525D915FEFF6, 0x5F1528B43AB810C2,
0xEC3B640A391F4FAD, 0x27E05A6E926952CC, 0x94CE16D091CE0DA3, 0xD3646C393A29F297, 0x604A2087398EADF8,
0x5C3099EA6DE60CFF, 0xEF1ED5546E415390, 0xA8B4AFBDC5A6ACA4, 0x1B9AE303C601F3CB, 0x56ED3E2F9E224471,
0xE5C372919D851B1E, 0xA26908783662E42A, 0x114744C635C5BB45, 0x2D3DFDAB61AD1A42, 0x9E13B115620A452D,
0xD9B9CBFCC9EDBA19, 0x6A978742CA4AE576, 0xA14CB926613CF817, 0x1262F598629BA778, 0x55C88F71C97C584C,
0xE6E6C3CFCADB0723, 0xDA9C7AA29EB3A624, 0x69B2361C9D14F94B, 0x2E184CF536F3067F, 0x9D36004B35545910,
0x2B769F17CF112238, 0x9858D3A9CCB67D57, 0xDFF2A94067518263, 0x6CDCE5FE64F6DD0C, 0x50A65C93309E7C0B,
0xE388102D33392364, 0xA4226AC498DEDC50, 0x170C267A9B79833F, 0xDCD7181E300F9E5E, 0x6FF954A033A8C131,
0x28532E49984F3E05, 0x9B7D62F79BE8616A, 0xA707DB9ACF80C06D, 0x14299724CC279F02, 0x5383EDCD67C06036,
0xE0ADA17364673F59
},
new ulong[]
{
0x0000000000000000, 0x54E979925CD0F10D, 0xA9D2F324B9A1E21A, 0xFD3B8AB6E5711317, 0xC17D4962DC4DDAB1,
0x959430F0809D2BBC, 0x68AFBA4665EC38AB, 0x3C46C3D4393CC9A6, 0x10223DEE1795ABE7, 0x44CB447C4B455AEA,
0xB9F0CECAAE3449FD, 0xED19B758F2E4B8F0, 0xD15F748CCBD87156, 0x85B60D1E9708805B, 0x788D87A87279934C,
0x2C64FE3A2EA96241, 0x20447BDC2F2B57CE, 0x74AD024E73FBA6C3, 0x899688F8968AB5D4, 0xDD7FF16ACA5A44D9,
0xE13932BEF3668D7F, 0xB5D04B2CAFB67C72, 0x48EBC19A4AC76F65, 0x1C02B80816179E68, 0x3066463238BEFC29,
0x648F3FA0646E0D24, 0x99B4B516811F1E33, 0xCD5DCC84DDCFEF3E, 0xF11B0F50E4F32698, 0xA5F276C2B823D795,
0x58C9FC745D52C482, 0x0C2085E60182358F, 0x4088F7B85E56AF9C, 0x14618E2A02865E91, 0xE95A049CE7F74D86,
0xBDB37D0EBB27BC8B, 0x81F5BEDA821B752D, 0xD51CC748DECB8420, 0x28274DFE3BBA9737, 0x7CCE346C676A663A,
0x50AACA5649C3047B, 0x0443B3C41513F576, 0xF9783972F062E661, 0xAD9140E0ACB2176C, 0x91D78334958EDECA,
0xC53EFAA6C95E2FC7, 0x380570102C2F3CD0, 0x6CEC098270FFCDDD, 0x60CC8C64717DF852, 0x3425F5F62DAD095F,
0xC91E7F40C8DC1A48, 0x9DF706D2940CEB45, 0xA1B1C506AD3022E3, 0xF558BC94F1E0D3EE, 0x086336221491C0F9,
0x5C8A4FB0484131F4, 0x70EEB18A66E853B5, 0x2407C8183A38A2B8, 0xD93C42AEDF49B1AF, 0x8DD53B3C839940A2,
0xB193F8E8BAA58904, 0xE57A817AE6757809, 0x18410BCC03046B1E, 0x4CA8725E5FD49A13, 0x8111EF70BCAD5F38,
0xD5F896E2E07DAE35, 0x28C31C54050CBD22, 0x7C2A65C659DC4C2F, 0x406CA61260E08589, 0x1485DF803C307484,
0xE9BE5536D9416793, 0xBD572CA48591969E, 0x9133D29EAB38F4DF, 0xC5DAAB0CF7E805D2, 0x38E121BA129916C5,
0x6C0858284E49E7C8, 0x504E9BFC77752E6E, 0x04A7E26E2BA5DF63, 0xF99C68D8CED4CC74, 0xAD75114A92043D79,
0xA15594AC938608F6, 0xF5BCED3ECF56F9FB, 0x088767882A27EAEC, 0x5C6E1E1A76F71BE1, 0x6028DDCE4FCBD247,
0x34C1A45C131B234A, 0xC9FA2EEAF66A305D, 0x9D135778AABAC150, 0xB177A9428413A311, 0xE59ED0D0D8C3521C,
0x18A55A663DB2410B, 0x4C4C23F46162B006, 0x700AE020585E79A0, 0x24E399B2048E88AD, 0xD9D81304E1FF9BBA,
0x8D316A96BD2F6AB7, 0xC19918C8E2FBF0A4, 0x9570615ABE2B01A9, 0x684BEBEC5B5A12BE, 0x3CA2927E078AE3B3,
0x00E451AA3EB62A15, 0x540D28386266DB18, 0xA936A28E8717C80F, 0xFDDFDB1CDBC73902, 0xD1BB2526F56E5B43,
0x85525CB4A9BEAA4E, 0x7869D6024CCFB959, 0x2C80AF90101F4854, 0x10C66C44292381F2, 0x442F15D675F370FF,
0xB9149F60908263E8, 0xEDFDE6F2CC5292E5, 0xE1DD6314CDD0A76A, 0xB5341A8691005667, 0x480F903074714570,
0x1CE6E9A228A1B47D, 0x20A02A76119D7DDB, 0x744953E44D4D8CD6, 0x8972D952A83C9FC1, 0xDD9BA0C0F4EC6ECC,
0xF1FF5EFADA450C8D, 0xA51627688695FD80, 0x582DADDE63E4EE97, 0x0CC4D44C3F341F9A, 0x308217980608D63C,
0x646B6E0A5AD82731, 0x9950E4BCBFA93426, 0xCDB99D2EE379C52B, 0x90FB71CAD654A0F5, 0xC41208588A8451F8,
0x392982EE6FF542EF, 0x6DC0FB7C3325B3E2, 0x518638A80A197A44, 0x056F413A56C98B49, 0xF854CB8CB3B8985E,
0xACBDB21EEF686953, 0x80D94C24C1C10B12, 0xD43035B69D11FA1F, 0x290BBF007860E908, 0x7DE2C69224B01805,
0x41A405461D8CD1A3, 0x154D7CD4415C20AE, 0xE876F662A42D33B9, 0xBC9F8FF0F8FDC2B4, 0xB0BF0A16F97FF73B,
0xE4567384A5AF0636, 0x196DF93240DE1521, 0x4D8480A01C0EE42C, 0x71C2437425322D8A, 0x252B3AE679E2DC87,
0xD810B0509C93CF90, 0x8CF9C9C2C0433E9D, 0xA09D37F8EEEA5CDC, 0xF4744E6AB23AADD1, 0x094FC4DC574BBEC6,
0x5DA6BD4E0B9B4FCB, 0x61E07E9A32A7866D, 0x350907086E777760, 0xC8328DBE8B066477, 0x9CDBF42CD7D6957A,
0xD073867288020F69, 0x849AFFE0D4D2FE64, 0x79A1755631A3ED73, 0x2D480CC46D731C7E, 0x110ECF10544FD5D8,
0x45E7B682089F24D5, 0xB8DC3C34EDEE37C2, 0xEC3545A6B13EC6CF, 0xC051BB9C9F97A48E, 0x94B8C20EC3475583,
0x698348B826364694, 0x3D6A312A7AE6B799, 0x012CF2FE43DA7E3F, 0x55C58B6C1F0A8F32, 0xA8FE01DAFA7B9C25,
0xFC177848A6AB6D28, 0xF037FDAEA72958A7, 0xA4DE843CFBF9A9AA, 0x59E50E8A1E88BABD, 0x0D0C771842584BB0,
0x314AB4CC7B648216, 0x65A3CD5E27B4731B, 0x989847E8C2C5600C, 0xCC713E7A9E159101, 0xE015C040B0BCF340,
0xB4FCB9D2EC6C024D, 0x49C73364091D115A, 0x1D2E4AF655CDE057, 0x216889226CF129F1, 0x7581F0B03021D8FC,
0x88BA7A06D550CBEB, 0xDC53039489803AE6, 0x11EA9EBA6AF9FFCD, 0x4503E72836290EC0, 0xB8386D9ED3581DD7,
0xECD1140C8F88ECDA, 0xD097D7D8B6B4257C, 0x847EAE4AEA64D471, 0x794524FC0F15C766, 0x2DAC5D6E53C5366B,
0x01C8A3547D6C542A, 0x5521DAC621BCA527, 0xA81A5070C4CDB630, 0xFCF329E2981D473D, 0xC0B5EA36A1218E9B,
0x945C93A4FDF17F96, 0x6967191218806C81, 0x3D8E608044509D8C, 0x31AEE56645D2A803, 0x65479CF41902590E,
0x987C1642FC734A19, 0xCC956FD0A0A3BB14, 0xF0D3AC04999F72B2, 0xA43AD596C54F83BF, 0x59015F20203E90A8,
0x0DE826B27CEE61A5, 0x218CD888524703E4, 0x7565A11A0E97F2E9, 0x885E2BACEBE6E1FE, 0xDCB7523EB73610F3,
0xE0F191EA8E0AD955, 0xB418E878D2DA2858, 0x492362CE37AB3B4F, 0x1DCA1B5C6B7BCA42, 0x5162690234AF5051,
0x058B1090687FA15C, 0xF8B09A268D0EB24B, 0xAC59E3B4D1DE4346, 0x901F2060E8E28AE0, 0xC4F659F2B4327BED,
0x39CDD344514368FA, 0x6D24AAD60D9399F7, 0x414054EC233AFBB6, 0x15A92D7E7FEA0ABB, 0xE892A7C89A9B19AC,
0xBC7BDE5AC64BE8A1, 0x803D1D8EFF772107, 0xD4D4641CA3A7D00A, 0x29EFEEAA46D6C31D, 0x7D0697381A063210,
0x712612DE1B84079F, 0x25CF6B4C4754F692, 0xD8F4E1FAA225E585, 0x8C1D9868FEF51488, 0xB05B5BBCC7C9DD2E,
0xE4B2222E9B192C23, 0x1989A8987E683F34, 0x4D60D10A22B8CE39, 0x61042F300C11AC78, 0x35ED56A250C15D75,
0xC8D6DC14B5B04E62, 0x9C3FA586E960BF6F, 0xA0796652D05C76C9, 0xF4901FC08C8C87C4, 0x09AB957669FD94D3,
0x5D42ECE4352D65DE
},
new ulong[]
{
0x0000000000000000, 0x3F0BE14A916A6DCB, 0x7E17C29522D4DB96, 0x411C23DFB3BEB65D, 0xFC2F852A45A9B72C,
0xC3246460D4C3DAE7, 0x823847BF677D6CBA, 0xBD33A6F5F6170171, 0x6A87A57F245D70DD, 0x558C4435B5371D16,
0x149067EA0689AB4B, 0x2B9B86A097E3C680, 0x96A8205561F4C7F1, 0xA9A3C11FF09EAA3A, 0xE8BFE2C043201C67,
0xD7B4038AD24A71AC, 0xD50F4AFE48BAE1BA, 0xEA04ABB4D9D08C71, 0xAB18886B6A6E3A2C, 0x94136921FB0457E7,
0x2920CFD40D135696, 0x162B2E9E9C793B5D, 0x57370D412FC78D00, 0x683CEC0BBEADE0CB, 0xBF88EF816CE79167,
0x80830ECBFD8DFCAC, 0xC19F2D144E334AF1, 0xFE94CC5EDF59273A, 0x43A76AAB294E264B, 0x7CAC8BE1B8244B80,
0x3DB0A83E0B9AFDDD, 0x02BB49749AF09016, 0x38C63AD73E7BDDF1, 0x07CDDB9DAF11B03A, 0x46D1F8421CAF0667,
0x79DA19088DC56BAC, 0xC4E9BFFD7BD26ADD, 0xFBE25EB7EAB80716, 0xBAFE7D685906B14B, 0x85F59C22C86CDC80,
0x52419FA81A26AD2C, 0x6D4A7EE28B4CC0E7, 0x2C565D3D38F276BA, 0x135DBC77A9981B71, 0xAE6E1A825F8F1A00,
0x9165FBC8CEE577CB, 0xD079D8177D5BC196, 0xEF72395DEC31AC5D, 0xEDC9702976C13C4B, 0xD2C29163E7AB5180,
0x93DEB2BC5415E7DD, 0xACD553F6C57F8A16, 0x11E6F50333688B67, 0x2EED1449A202E6AC, 0x6FF1379611BC50F1,
0x50FAD6DC80D63D3A, 0x874ED556529C4C96, 0xB845341CC3F6215D, 0xF95917C370489700, 0xC652F689E122FACB,
0x7B61507C1735FBBA, 0x446AB136865F9671, 0x057692E935E1202C, 0x3A7D73A3A48B4DE7, 0x718C75AE7CF7BBE2,
0x4E8794E4ED9DD629, 0x0F9BB73B5E236074, 0x30905671CF490DBF, 0x8DA3F084395E0CCE, 0xB2A811CEA8346105,
0xF3B432111B8AD758, 0xCCBFD35B8AE0BA93, 0x1B0BD0D158AACB3F, 0x2400319BC9C0A6F4, 0x651C12447A7E10A9,
0x5A17F30EEB147D62, 0xE72455FB1D037C13, 0xD82FB4B18C6911D8, 0x9933976E3FD7A785, 0xA6387624AEBDCA4E,
0xA4833F50344D5A58, 0x9B88DE1AA5273793, 0xDA94FDC5169981CE, 0xE59F1C8F87F3EC05, 0x58ACBA7A71E4ED74,
0x67A75B30E08E80BF, 0x26BB78EF533036E2, 0x19B099A5C25A5B29, 0xCE049A2F10102A85, 0xF10F7B65817A474E,
0xB01358BA32C4F113, 0x8F18B9F0A3AE9CD8, 0x322B1F0555B99DA9, 0x0D20FE4FC4D3F062, 0x4C3CDD90776D463F,
0x73373CDAE6072BF4, 0x494A4F79428C6613, 0x7641AE33D3E60BD8, 0x375D8DEC6058BD85, 0x08566CA6F132D04E,
0xB565CA530725D13F, 0x8A6E2B19964FBCF4, 0xCB7208C625F10AA9, 0xF479E98CB49B6762, 0x23CDEA0666D116CE,
0x1CC60B4CF7BB7B05, 0x5DDA28934405CD58, 0x62D1C9D9D56FA093, 0xDFE26F2C2378A1E2, 0xE0E98E66B212CC29,
0xA1F5ADB901AC7A74, 0x9EFE4CF390C617BF, 0x9C4505870A3687A9, 0xA34EE4CD9B5CEA62, 0xE252C71228E25C3F,
0xDD592658B98831F4, 0x606A80AD4F9F3085, 0x5F6161E7DEF55D4E, 0x1E7D42386D4BEB13, 0x2176A372FC2186D8,
0xF6C2A0F82E6BF774, 0xC9C941B2BF019ABF, 0x88D5626D0CBF2CE2, 0xB7DE83279DD54129, 0x0AED25D26BC24058,
0x35E6C498FAA82D93, 0x74FAE74749169BCE, 0x4BF1060DD87CF605, 0xE318EB5CF9EF77C4, 0xDC130A1668851A0F,
0x9D0F29C9DB3BAC52, 0xA204C8834A51C199, 0x1F376E76BC46C0E8, 0x203C8F3C2D2CAD23, 0x6120ACE39E921B7E,
0x5E2B4DA90FF876B5, 0x899F4E23DDB20719, 0xB694AF694CD86AD2, 0xF7888CB6FF66DC8F, 0xC8836DFC6E0CB144,
0x75B0CB09981BB035, 0x4ABB2A430971DDFE, 0x0BA7099CBACF6BA3, 0x34ACE8D62BA50668, 0x3617A1A2B155967E,
0x091C40E8203FFBB5, 0x4800633793814DE8, 0x770B827D02EB2023, 0xCA382488F4FC2152, 0xF533C5C265964C99,
0xB42FE61DD628FAC4, 0x8B2407574742970F, 0x5C9004DD9508E6A3, 0x639BE59704628B68, 0x2287C648B7DC3D35,
0x1D8C270226B650FE, 0xA0BF81F7D0A1518F, 0x9FB460BD41CB3C44, 0xDEA84362F2758A19, 0xE1A3A228631FE7D2,
0xDBDED18BC794AA35, 0xE4D530C156FEC7FE, 0xA5C9131EE54071A3, 0x9AC2F254742A1C68, 0x27F154A1823D1D19,
0x18FAB5EB135770D2, 0x59E69634A0E9C68F, 0x66ED777E3183AB44, 0xB15974F4E3C9DAE8, 0x8E5295BE72A3B723,
0xCF4EB661C11D017E, 0xF045572B50776CB5, 0x4D76F1DEA6606DC4, 0x727D1094370A000F, 0x3361334B84B4B652,
0x0C6AD20115DEDB99, 0x0ED19B758F2E4B8F, 0x31DA7A3F1E442644, 0x70C659E0ADFA9019, 0x4FCDB8AA3C90FDD2,
0xF2FE1E5FCA87FCA3, 0xCDF5FF155BED9168, 0x8CE9DCCAE8532735, 0xB3E23D8079394AFE, 0x64563E0AAB733B52,
0x5B5DDF403A195699, 0x1A41FC9F89A7E0C4, 0x254A1DD518CD8D0F, 0x9879BB20EEDA8C7E, 0xA7725A6A7FB0E1B5,
0xE66E79B5CC0E57E8, 0xD96598FF5D643A23, 0x92949EF28518CC26, 0xAD9F7FB81472A1ED, 0xEC835C67A7CC17B0,
0xD388BD2D36A67A7B, 0x6EBB1BD8C0B17B0A, 0x51B0FA9251DB16C1, 0x10ACD94DE265A09C, 0x2FA73807730FCD57,
0xF8133B8DA145BCFB, 0xC718DAC7302FD130, 0x8604F9188391676D, 0xB90F185212FB0AA6, 0x043CBEA7E4EC0BD7,
0x3B375FED7586661C, 0x7A2B7C32C638D041, 0x45209D785752BD8A, 0x479BD40CCDA22D9C, 0x789035465CC84057,
0x398C1699EF76F60A, 0x0687F7D37E1C9BC1, 0xBBB45126880B9AB0, 0x84BFB06C1961F77B, 0xC5A393B3AADF4126,
0xFAA872F93BB52CED, 0x2D1C7173E9FF5D41, 0x121790397895308A, 0x530BB3E6CB2B86D7, 0x6C0052AC5A41EB1C,
0xD133F459AC56EA6D, 0xEE3815133D3C87A6, 0xAF2436CC8E8231FB, 0x902FD7861FE85C30, 0xAA52A425BB6311D7,
0x9559456F2A097C1C, 0xD44566B099B7CA41, 0xEB4E87FA08DDA78A, 0x567D210FFECAA6FB, 0x6976C0456FA0CB30,
0x286AE39ADC1E7D6D, 0x176102D04D7410A6, 0xC0D5015A9F3E610A, 0xFFDEE0100E540CC1, 0xBEC2C3CFBDEABA9C,
0x81C922852C80D757, 0x3CFA8470DA97D626, 0x03F1653A4BFDBBED, 0x42ED46E5F8430DB0, 0x7DE6A7AF6929607B,
0x7F5DEEDBF3D9F06D, 0x40560F9162B39DA6, 0x014A2C4ED10D2BFB, 0x3E41CD0440674630, 0x83726BF1B6704741,
0xBC798ABB271A2A8A, 0xFD65A96494A49CD7, 0xC26E482E05CEF11C, 0x15DA4BA4D78480B0, 0x2AD1AAEE46EEED7B,
0x6BCD8931F5505B26, 0x54C6687B643A36ED, 0xE9F5CE8E922D379C, 0xD6FE2FC403475A57, 0x97E20C1BB0F9EC0A,
0xA8E9ED51219381C1
},
new ulong[]
{
0x0000000000000000, 0x1DEE8A5E222CA1DC, 0x3BDD14BC445943B8, 0x26339EE26675E264, 0x77BA297888B28770,
0x6A54A326AA9E26AC, 0x4C673DC4CCEBC4C8, 0x5189B79AEEC76514, 0xEF7452F111650EE0, 0xF29AD8AF3349AF3C,
0xD4A9464D553C4D58, 0xC947CC137710EC84, 0x98CE7B8999D78990, 0x8520F1D7BBFB284C, 0xA3136F35DD8ECA28,
0xBEFDE56BFFA26BF4, 0x4C300AC98DC40345, 0x51DE8097AFE8A299, 0x77ED1E75C99D40FD, 0x6A03942BEBB1E121,
0x3B8A23B105768435, 0x2664A9EF275A25E9, 0x0057370D412FC78D, 0x1DB9BD5363036651, 0xA34458389CA10DA5,
0xBEAAD266BE8DAC79, 0x98994C84D8F84E1D, 0x8577C6DAFAD4EFC1, 0xD4FE714014138AD5, 0xC910FB1E363F2B09,
0xEF2365FC504AC96D, 0xF2CDEFA2726668B1, 0x986015931B88068A, 0x858E9FCD39A4A756, 0xA3BD012F5FD14532,
0xBE538B717DFDE4EE, 0xEFDA3CEB933A81FA, 0xF234B6B5B1162026, 0xD4072857D763C242, 0xC9E9A209F54F639E,
0x771447620AED086A, 0x6AFACD3C28C1A9B6, 0x4CC953DE4EB44BD2, 0x5127D9806C98EA0E, 0x00AE6E1A825F8F1A,
0x1D40E444A0732EC6, 0x3B737AA6C606CCA2, 0x269DF0F8E42A6D7E, 0xD4501F5A964C05CF, 0xC9BE9504B460A413,
0xEF8D0BE6D2154677, 0xF26381B8F039E7AB, 0xA3EA36221EFE82BF, 0xBE04BC7C3CD22363, 0x9837229E5AA7C107,
0x85D9A8C0788B60DB, 0x3B244DAB87290B2F, 0x26CAC7F5A505AAF3, 0x00F95917C3704897, 0x1D17D349E15CE94B,
0x4C9E64D30F9B8C5F, 0x5170EE8D2DB72D83, 0x7743706F4BC2CFE7, 0x6AADFA3169EE6E3B, 0xA218840D981E1391,
0xBFF60E53BA32B24D, 0x99C590B1DC475029, 0x842B1AEFFE6BF1F5, 0xD5A2AD7510AC94E1, 0xC84C272B3280353D,
0xEE7FB9C954F5D759, 0xF391339776D97685, 0x4D6CD6FC897B1D71, 0x50825CA2AB57BCAD, 0x76B1C240CD225EC9,
0x6B5F481EEF0EFF15, 0x3AD6FF8401C99A01, 0x273875DA23E53BDD, 0x010BEB384590D9B9, 0x1CE5616667BC7865,
0xEE288EC415DA10D4, 0xF3C6049A37F6B108, 0xD5F59A785183536C, 0xC81B102673AFF2B0, 0x9992A7BC9D6897A4,
0x847C2DE2BF443678, 0xA24FB300D931D41C, 0xBFA1395EFB1D75C0, 0x015CDC3504BF1E34, 0x1CB2566B2693BFE8,
0x3A81C88940E65D8C, 0x276F42D762CAFC50, 0x76E6F54D8C0D9944, 0x6B087F13AE213898, 0x4D3BE1F1C854DAFC,
0x50D56BAFEA787B20, 0x3A78919E8396151B, 0x27961BC0A1BAB4C7, 0x01A58522C7CF56A3, 0x1C4B0F7CE5E3F77F,
0x4DC2B8E60B24926B, 0x502C32B8290833B7, 0x761FAC5A4F7DD1D3, 0x6BF126046D51700F, 0xD50CC36F92F31BFB,
0xC8E24931B0DFBA27, 0xEED1D7D3D6AA5843, 0xF33F5D8DF486F99F, 0xA2B6EA171A419C8B, 0xBF586049386D3D57,
0x996BFEAB5E18DF33, 0x848574F57C347EEF, 0x76489B570E52165E, 0x6BA611092C7EB782, 0x4D958FEB4A0B55E6,
0x507B05B56827F43A, 0x01F2B22F86E0912E, 0x1C1C3871A4CC30F2, 0x3A2FA693C2B9D296, 0x27C12CCDE095734A,
0x993CC9A61F3718BE, 0x84D243F83D1BB962, 0xA2E1DD1A5B6E5B06, 0xBF0F57447942FADA, 0xEE86E0DE97859FCE,
0xF3686A80B5A93E12, 0xD55BF462D3DCDC76, 0xC8B57E3CF1F07DAA, 0xD6E9A7309F3239A7, 0xCB072D6EBD1E987B,
0xED34B38CDB6B7A1F, 0xF0DA39D2F947DBC3, 0xA1538E481780BED7, 0xBCBD041635AC1F0B, 0x9A8E9AF453D9FD6F,
0x876010AA71F55CB3, 0x399DF5C18E573747, 0x24737F9FAC7B969B, 0x0240E17DCA0E74FF, 0x1FAE6B23E822D523,
0x4E27DCB906E5B037, 0x53C956E724C911EB, 0x75FAC80542BCF38F, 0x6814425B60905253, 0x9AD9ADF912F63AE2,
0x873727A730DA9B3E, 0xA104B94556AF795A, 0xBCEA331B7483D886, 0xED6384819A44BD92, 0xF08D0EDFB8681C4E,
0xD6BE903DDE1DFE2A, 0xCB501A63FC315FF6, 0x75ADFF0803933402, 0x6843755621BF95DE, 0x4E70EBB447CA77BA,
0x539E61EA65E6D666, 0x0217D6708B21B372, 0x1FF95C2EA90D12AE, 0x39CAC2CCCF78F0CA, 0x24244892ED545116,
0x4E89B2A384BA3F2D, 0x536738FDA6969EF1, 0x7554A61FC0E37C95, 0x68BA2C41E2CFDD49, 0x39339BDB0C08B85D,
0x24DD11852E241981, 0x02EE8F674851FBE5, 0x1F0005396A7D5A39, 0xA1FDE05295DF31CD, 0xBC136A0CB7F39011,
0x9A20F4EED1867275, 0x87CE7EB0F3AAD3A9, 0xD647C92A1D6DB6BD, 0xCBA943743F411761, 0xED9ADD965934F505,
0xF07457C87B1854D9, 0x02B9B86A097E3C68, 0x1F5732342B529DB4, 0x3964ACD64D277FD0, 0x248A26886F0BDE0C,
0x7503911281CCBB18, 0x68ED1B4CA3E01AC4, 0x4EDE85AEC595F8A0, 0x53300FF0E7B9597C, 0xEDCDEA9B181B3288,
0xF02360C53A379354, 0xD610FE275C427130, 0xCBFE74797E6ED0EC, 0x9A77C3E390A9B5F8, 0x879949BDB2851424,
0xA1AAD75FD4F0F640, 0xBC445D01F6DC579C, 0x74F1233D072C2A36, 0x691FA96325008BEA, 0x4F2C37814375698E,
0x52C2BDDF6159C852, 0x034B0A458F9EAD46, 0x1EA5801BADB20C9A, 0x38961EF9CBC7EEFE, 0x257894A7E9EB4F22,
0x9B8571CC164924D6, 0x866BFB923465850A, 0xA05865705210676E, 0xBDB6EF2E703CC6B2, 0xEC3F58B49EFBA3A6,
0xF1D1D2EABCD7027A, 0xD7E24C08DAA2E01E, 0xCA0CC656F88E41C2, 0x38C129F48AE82973, 0x252FA3AAA8C488AF,
0x031C3D48CEB16ACB, 0x1EF2B716EC9DCB17, 0x4F7B008C025AAE03, 0x52958AD220760FDF, 0x74A614304603EDBB,
0x69489E6E642F4C67, 0xD7B57B059B8D2793, 0xCA5BF15BB9A1864F, 0xEC686FB9DFD4642B, 0xF186E5E7FDF8C5F7,
0xA00F527D133FA0E3, 0xBDE1D8233113013F, 0x9BD246C15766E35B, 0x863CCC9F754A4287, 0xEC9136AE1CA42CBC,
0xF17FBCF03E888D60, 0xD74C221258FD6F04, 0xCAA2A84C7AD1CED8, 0x9B2B1FD69416ABCC, 0x86C59588B63A0A10,
0xA0F60B6AD04FE874, 0xBD188134F26349A8, 0x03E5645F0DC1225C, 0x1E0BEE012FED8380, 0x383870E3499861E4,
0x25D6FABD6BB4C038, 0x745F4D278573A52C, 0x69B1C779A75F04F0, 0x4F82599BC12AE694, 0x526CD3C5E3064748,
0xA0A13C6791602FF9, 0xBD4FB639B34C8E25, 0x9B7C28DBD5396C41, 0x8692A285F715CD9D, 0xD71B151F19D2A889,
0xCAF59F413BFE0955, 0xECC601A35D8BEB31, 0xF1288BFD7FA74AED, 0x4FD56E9680052119, 0x523BE4C8A22980C5,
0x74087A2AC45C62A1, 0x69E6F074E670C37D, 0x386F47EE08B7A669, 0x2581CDB02A9B07B5, 0x03B253524CEEE5D1,
0x1E5CD90C6EC2440D
}
};
readonly ulong _finalSeed;
readonly IntPtr _nativeContext;
readonly ulong[][]? _table;
readonly bool _useEcma;
readonly bool _useNative;
ulong _hashInt;
/// <summary>Initializes the CRC64 table and seed as CRC64-ECMA</summary>
public Crc64Context()
{
_hashInt = CRC64_ECMA_SEED;
_table = _ecmaCrc64Table;
_finalSeed = CRC64_ECMA_SEED;
_useEcma = true;
if(!Native.IsSupported)
return;
_nativeContext = crc64_init();
_useNative = _nativeContext != IntPtr.Zero;
}
/// <summary>Initializes the CRC16 table with a custom polynomial and seed</summary>
public Crc64Context(ulong polynomial, ulong seed)
{
_hashInt = seed;
_finalSeed = seed;
_useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
if(Native.IsSupported && _useEcma)
{
_nativeContext = crc64_init();
_useNative = _nativeContext != IntPtr.Zero;
}
else
_table = GenerateTable(polynomial);
}
#region IChecksum Members
/// <inheritdoc />
public string Name => "CRC-64 (ECMA)";
/// <inheritdoc />
public Guid Id => new("D0C0D902-420A-45DA-A235-9D48BEE4B1CE");
/// <inheritdoc />
public string Author => "Natalia Portillo";
/// <inheritdoc />
/// <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) =>
Step(ref _hashInt, _table!, data, len, _useEcma, _useNative, _nativeContext);
/// <inheritdoc />
/// <summary>Updates the hash with data.</summary>
/// <param name="data">Data buffer.</param>
public void Update(byte[] data) => Update(data, (uint)data.Length);
/// <inheritdoc />
/// <summary>Returns a byte array of the hash value.</summary>
public byte[] Final()
{
ulong crc = _hashInt ^ _finalSeed;
if(!_useNative || !_useEcma)
return BigEndianBitConverter.GetBytes(crc);
crc64_final(_nativeContext, ref crc);
crc64_free(_nativeContext);
return BigEndianBitConverter.GetBytes(crc);
}
/// <inheritdoc />
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
public string End()
{
ulong crc = _hashInt ^ _finalSeed;
var crc64Output = new StringBuilder();
if(_useNative && _useEcma)
{
crc64_final(_nativeContext, ref crc);
crc64_free(_nativeContext);
}
for(var i = 0; i < BigEndianBitConverter.GetBytes(crc).Length; i++)
crc64Output.Append(BigEndianBitConverter.GetBytes(crc)[i].ToString("x2"));
return crc64Output.ToString();
}
#endregion
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern IntPtr crc64_init();
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int crc64_update(IntPtr ctx, byte[] data, uint len);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int crc64_final(IntPtr ctx, ref ulong crc);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern void crc64_free(IntPtr ctx);
static ulong[][] GenerateTable(ulong polynomial)
{
var table = new ulong[8][];
for(var i = 0; i < 8; i++)
table[i] = new ulong[256];
for(var i = 0; i < 256; i++)
{
var entry = (ulong)i;
for(var j = 0; j < 8; j++)
{
if((entry & 1) == 1)
entry = entry >> 1 ^ polynomial;
else
entry >>= 1;
}
table[0][i] = entry;
}
for(var slice = 1; slice < 4; slice++)
for(var i = 0; i < 256; i++)
table[slice][i] = table[slice - 1][i] >> 8 ^ table[0][table[slice - 1][i] & 0xFF];
return table;
}
static void Step(ref ulong previousCrc, ulong[][] table, byte[] data, uint len, bool useEcma, bool useNative,
IntPtr nativeContext)
{
if(useNative && useEcma)
{
crc64_update(nativeContext, data, len);
return;
}
var dataOff = 0;
#if NETCOREAPP3_1_OR_GREATER
if(useEcma && Pclmulqdq.IsSupported && Sse41.IsSupported && Ssse3.IsSupported && Sse2.IsSupported)
{
// Only works in blocks of 32 bytes
uint blocks = len / 32;
if(blocks > 0)
{
previousCrc = ~Clmul.Step(~previousCrc, data, blocks * 32);
dataOff = (int)(blocks * 32);
len -= blocks * 32;
}
if(len == 0)
return;
}
#endif
// Unroll according to Intel slicing by uint8_t
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
// http://sourceforge.net/projects/slicing-by-8/
ulong crc = previousCrc;
if(len > 4)
{
long limit = dataOff + (len & ~(uint)3);
len &= 3;
while(dataOff < limit)
{
var tmp = (uint)(crc ^ BitConverter.ToUInt32(data, dataOff));
dataOff += 4;
crc = table[3][tmp & 0xFF] ^
table[2][tmp >> 8 & 0xFF] ^
crc >> 32 ^
table[1][tmp >> 16 & 0xFF] ^
table[0][tmp >> 24];
}
}
while(len-- != 0)
crc = table[0][data[dataOff++] ^ crc & 0xFF] ^ crc >> 8;
previousCrc = crc;
}
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
public static byte[] File(string filename)
{
File(filename, out byte[] localHash);
return localHash;
}
/// <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) =>
File(filename, out hash, CRC64_ECMA_POLY, CRC64_ECMA_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>
/// <param name="polynomial">CRC polynomial</param>
/// <param name="seed">CRC seed</param>
public static string File(string filename, out byte[] hash, ulong polynomial, ulong seed)
{
bool useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
bool useNative = Native.IsSupported;
IntPtr nativeContext = IntPtr.Zero;
if(useNative && useEcma)
{
nativeContext = crc64_init();
useNative = nativeContext != IntPtr.Zero;
}
var fileStream = new FileStream(filename, FileMode.Open);
ulong localHashInt = seed;
ulong[][] localTable = GenerateTable(polynomial);
var buffer = new byte[65536];
int read = fileStream.EnsureRead(buffer, 0, 65536);
while(read > 0)
{
Step(ref localHashInt, localTable, buffer, (uint)read, useEcma, useNative, nativeContext);
read = fileStream.EnsureRead(buffer, 0, 65536);
}
localHashInt ^= seed;
if(useNative && useEcma)
{
crc64_final(nativeContext, ref localHashInt);
crc64_free(nativeContext);
}
hash = BigEndianBitConverter.GetBytes(localHashInt);
var crc64Output = new StringBuilder();
foreach(byte h in hash)
crc64Output.Append(h.ToString("x2"));
fileStream.Close();
return crc64Output.ToString();
}
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of the data buffer to hash.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, uint len, out byte[] hash) =>
Data(data, len, out hash, CRC64_ECMA_POLY, CRC64_ECMA_SEED);
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of the data buffer to hash.</param>
/// <param name="hash">Byte array of the hash value.</param>
/// <param name="polynomial">CRC polynomial</param>
/// <param name="seed">CRC seed</param>
public static string Data(byte[] data, uint len, out byte[] hash, ulong polynomial, ulong seed)
{
bool useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
bool useNative = Native.IsSupported;
IntPtr nativeContext = IntPtr.Zero;
if(useNative && useEcma)
{
nativeContext = crc64_init();
useNative = nativeContext != IntPtr.Zero;
}
ulong localHashInt = seed;
ulong[][] localTable = GenerateTable(polynomial);
Step(ref localHashInt, localTable, data, len, useEcma, useNative, nativeContext);
localHashInt ^= seed;
if(useNative && useEcma)
{
crc64_final(nativeContext, ref localHashInt);
crc64_free(nativeContext);
}
hash = BigEndianBitConverter.GetBytes(localHashInt);
var crc64Output = new StringBuilder();
foreach(byte h in hash)
crc64Output.Append(h.ToString("x2"));
return crc64Output.ToString();
}
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
}

View File

@@ -48,6 +48,7 @@ using Aaru.Helpers;
#if NETCOREAPP3_1_OR_GREATER
using Ssse3 = System.Runtime.Intrinsics.X86.Ssse3;
#endif
using static Aaru.Helpers.Extensions;
namespace Aaru.Checksums;
@@ -357,13 +358,13 @@ public sealed class Fletcher32Context : IChecksum
ushort localSum2 = 0xFFFF;
var buffer = new byte[65536];
int read = fileStream.EnsureRead(buffer, 0, 65536);
int read = EnsureRead(fileStream, buffer, 0, 65536);
while(read > 0)
{
Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
read = fileStream.EnsureRead(buffer, 0, 65536);
read = EnsureRead(fileStream, buffer, 0, 65536);
}
var finalSum = (uint)(localSum2 << 16 | localSum1);
@@ -701,13 +702,13 @@ public sealed class Fletcher16Context : IChecksum
byte localSum2 = 0xFF;
var buffer = new byte[65536];
int read = fileStream.EnsureRead(buffer, 0, 65536);
int read = EnsureRead(fileStream, buffer, 0, 65536);
while(read > 0)
{
Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
read = fileStream.EnsureRead(buffer, 0, 65536);
read = EnsureRead(fileStream, buffer, 0, 65536);
}
var finalSum = (ushort)(localSum2 << 8 | localSum1);

View File

@@ -65,7 +65,7 @@ internal sealed class SpamSumContext : IChecksum
const uint FUZZY_MAX_RESULT = 2 * SPAMSUM_LENGTH + 20;
//"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#if NET20 || NET35 || NET40
#if NET20 || NET35 || NET40 || NET452
readonly byte[] _b64 = Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
#else
readonly byte[] _b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"u8.ToArray();

View File

@@ -31,7 +31,6 @@
// ****************************************************************************/
using System;
using System.Linq;
namespace Aaru.Helpers
{
@@ -50,52 +49,52 @@ namespace Aaru.Helpers
/// <summary>Returns the specified Boolean value as an array of bytes.</summary>
/// <param name="value">A Boolean value.</param>
/// <returns>An array of bytes with length 1.</returns>
public static byte[] GetBytes(bool value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(bool value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified Unicode character value as an array of bytes.</summary>
/// <param name="value">A character to convert.</param>
/// <returns>An array of bytes with length 2.</returns>
public static byte[] GetBytes(char value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(char value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified double-precision floating point value as an array of bytes.</summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 8.</returns>
public static byte[] GetBytes(double value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(double value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified single-precision floating point value as an array of bytes.</summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 4.</returns>
public static byte[] GetBytes(float value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(float value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified 32-bit signed integer value as an array of bytes.</summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 4.</returns>
public static byte[] GetBytes(int value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(int value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified 64-bit signed integer value as an array of bytes.</summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 8.</returns>
public static byte[] GetBytes(long value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(long value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified 16-bit signed integer value as an array of bytes.</summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 2.</returns>
public static byte[] GetBytes(short value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(short value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified 32-bit unsigned integer value as an array of bytes.</summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 4.</returns>
public static byte[] GetBytes(uint value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(uint value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified 64-bit unsigned integer value as an array of bytes.</summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 8.</returns>
public static byte[] GetBytes(ulong value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(ulong value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Returns the specified 16-bit unsigned integer value as an array of bytes.</summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 2.</returns>
public static byte[] GetBytes(ushort value) => BitConverter.GetBytes(value).Reverse().ToArray();
public static byte[] GetBytes(ushort value) => Reverse(BitConverter.GetBytes(value));
/// <summary>Converts the specified 64-bit signed integer to a double-precision floating point number.</summary>
/// <param name="value">The number to convert.</param>
@@ -154,7 +153,7 @@ namespace Aaru.Helpers
/// minus 1.
/// </exception>
public static short ToInt16(byte[] value, int startIndex) =>
BitConverter.ToInt16(value.Reverse().ToArray(), value.Length - sizeof(short) - startIndex);
BitConverter.ToInt16(Reverse(value), value.Length - sizeof(short) - startIndex);
/// <summary>Returns a 32-bit signed integer converted from four bytes at a specified position in a byte array.</summary>
/// <param name="value">An array of bytes.</param>
@@ -170,7 +169,7 @@ namespace Aaru.Helpers
/// minus 1.
/// </exception>
public static int ToInt32(byte[] value, int startIndex) =>
BitConverter.ToInt32(value.Reverse().ToArray(), value.Length - sizeof(int) - startIndex);
BitConverter.ToInt32(Reverse(value), value.Length - sizeof(int) - startIndex);
/// <summary>Returns a 64-bit signed integer converted from eight bytes at a specified position in a byte array.</summary>
/// <param name="value">An array of bytes.</param>
@@ -186,7 +185,7 @@ namespace Aaru.Helpers
/// length of value minus 1.
/// </exception>
public static long ToInt64(byte[] value, int startIndex) =>
BitConverter.ToInt64(value.Reverse().ToArray(), value.Length - sizeof(long) - startIndex);
BitConverter.ToInt64(Reverse(value), value.Length - sizeof(long) - startIndex);
/// <summary>
/// Returns a single-precision floating point number converted from four bytes at a specified position in a byte
@@ -205,7 +204,7 @@ namespace Aaru.Helpers
/// length of value minus 1.
/// </exception>
public static float ToSingle(byte[] value, int startIndex) =>
BitConverter.ToSingle(value.Reverse().ToArray(), value.Length - sizeof(float) - startIndex);
BitConverter.ToSingle(Reverse(value), value.Length - sizeof(float) - startIndex);
/// <summary>
/// Converts the numeric value of each element of a specified array of bytes to its equivalent hexadecimal string
@@ -217,7 +216,7 @@ namespace Aaru.Helpers
/// element in value; for example, "7F-2C-4A".
/// </returns>
/// <exception cref="System.ArgumentNullException">value is null.</exception>
public static string ToString(byte[] value) => BitConverter.ToString(value.Reverse().ToArray());
public static string ToString(byte[] value) => BitConverter.ToString(Reverse(value));
/// <summary>
/// Converts the numeric value of each element of a specified subarray of bytes to its equivalent hexadecimal
@@ -235,7 +234,7 @@ namespace Aaru.Helpers
/// minus 1.
/// </exception>
public static string ToString(byte[] value, int startIndex) =>
BitConverter.ToString(value.Reverse().ToArray(), startIndex);
BitConverter.ToString(Reverse(value), startIndex);
/// <summary>
/// Converts the numeric value of each element of a specified subarray of bytes to its equivalent hexadecimal
@@ -258,7 +257,7 @@ namespace Aaru.Helpers
/// value; that is, the startIndex parameter is greater than the length of value minus the length parameter.
/// </exception>
public static string ToString(byte[] value, int startIndex, int length) =>
BitConverter.ToString(value.Reverse().ToArray(), startIndex, length);
BitConverter.ToString(Reverse(value), startIndex, length);
/// <summary>Returns a 16-bit unsigned integer converted from two bytes at a specified position in a byte array.</summary>
/// <param name="value">The array of bytes.</param>
@@ -271,7 +270,7 @@ namespace Aaru.Helpers
/// minus 1.
/// </exception>
public static ushort ToUInt16(byte[] value, int startIndex) =>
BitConverter.ToUInt16(value.Reverse().ToArray(), value.Length - sizeof(ushort) - startIndex);
BitConverter.ToUInt16(Reverse(value), value.Length - sizeof(ushort) - startIndex);
/// <summary>Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array.</summary>
/// <param name="value">An array of bytes.</param>
@@ -287,7 +286,7 @@ namespace Aaru.Helpers
/// minus 1.
/// </exception>
public static uint ToUInt32(byte[] value, int startIndex) =>
BitConverter.ToUInt32(value.Reverse().ToArray(), value.Length - sizeof(uint) - startIndex);
BitConverter.ToUInt32(Reverse(value), value.Length - sizeof(uint) - startIndex);
/// <summary>Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array.</summary>
/// <param name="value">An array of bytes.</param>
@@ -303,7 +302,7 @@ namespace Aaru.Helpers
/// minus 1.
/// </exception>
public static ulong ToUInt64(byte[] value, int startIndex) =>
BitConverter.ToUInt64(value.Reverse().ToArray(), value.Length - sizeof(ulong) - startIndex);
BitConverter.ToUInt64(Reverse(value), value.Length - sizeof(ulong) - startIndex);
/// <summary>Converts a big endian byte array representation of a GUID into the .NET Guid structure</summary>
/// <param name="value">Byte array containing a GUID in big endian</param>
@@ -320,5 +319,13 @@ namespace Aaru.Helpers
value[8 + startIndex + 5],
value[8 + startIndex + 6],
value[8 + startIndex + 7]);
// Additional helper method to replace single Linq use
private static T[] Reverse<T>(T[] value)
{
Array.Reverse(value);
return value;
}
}
}

View File

@@ -56,7 +56,7 @@ public static class Extensions
/// The total number of bytes read into the buffer. This can be less than the number of bytes requested if the end
/// of the stream has been reached.
/// </returns>
public static int EnsureRead(this Stream s, byte[] buffer, int offset, int count)
public static int EnsureRead(Stream s, byte[] buffer, int offset, int count)
{
var pos = 0;
int read;

View File

@@ -1,68 +0,0 @@
using System;
namespace CRC32
{
public class NaiveCRC
{
private const uint kPoly = 0xEDB88320;
private const uint kInit = 0xFFFFFFFF;
private static readonly uint[] Table;
static NaiveCRC()
{
unchecked
{
Table = new uint[256];
for (uint i = 0; i < 256; i++)
{
uint r = i;
for (int j = 0; j < 8; j++)
r = (r >> 1) ^ (kPoly & ~((r & 1) - 1));
Table[i] = r;
}
}
}
private uint value;
public NaiveCRC()
{
Init();
}
public void Init()
{
value = kInit;
}
public int Value
{
get { return (int)~value; }
}
public void UpdateByte(byte b)
{
value = (value >> 8) ^ Table[(byte)value ^ b];
}
public void Update(byte[] data, int offset, int count)
{
if (count < 0) throw new ArgumentOutOfRangeException("count");
while (count-- != 0)
value = (value >> 8) ^ Table[(byte)value ^ data[offset++]];
}
static public int Compute(byte[] data, int offset, int count)
{
var crc = new NaiveCRC();
crc.Update(data, offset, count);
return crc.Value;
}
static public int Compute(byte[] data)
{
return Compute(data, 0, data.Length);
}
}
}

View File

@@ -1,110 +0,0 @@
/*
* Copyright (c) 2012-2015 Eugene Larchenko (el6345@gmail.com)
* This code is licensed under the MIT License.
* See the file LICENSE_MIT for the license details.
*/
using System;
namespace CRC32
{
public class OptimizedCRC
{
private const uint kPoly = 0xEDB88320;
private const uint kInit = 0xFFFFFFFF;
private const int NUM_TABLES = 8;
private static readonly uint[] Table;
static OptimizedCRC()
{
unchecked
{
Table = new uint[256 * NUM_TABLES];
int i;
for (i = 0; i < 256; i++)
{
uint r = (uint)i;
for (int j = 0; j < 8; j++)
r = (r >> 1) ^ (kPoly & ~((r & 1) - 1));
Table[i] = r;
}
for (; i < 256 * NUM_TABLES; i++)
{
uint r = Table[i - 256];
Table[i] = Table[r & 0xFF] ^ (r >> 8);
}
}
}
private uint value;
public OptimizedCRC()
{
Init();
}
public void Init()
{
value = kInit;
}
public int Value
{
get { return (int)~value; }
}
public void Update(byte[] data, int offset, int count)
{
new ArraySegment<byte>(data, offset, count); // check arguments
if (count <= 0) return;
var table = OptimizedCRC.Table;
uint crc = value;
for (; (offset & 7) != 0 && count != 0; count--)
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
if (count >= 8)
{
int end = (count - 8) & ~7;
count -= end;
end += offset;
while (offset != end)
{
crc ^= (uint)(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) + (data[offset + 3] << 24));
uint high = (uint)(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) + (data[offset + 7] << 24));
offset += 8;
crc = table[(byte)crc + 0x700]
^ table[(byte)(crc >>= 8) + 0x600]
^ table[(byte)(crc >>= 8) + 0x500]
^ table[/*(byte)*/(crc >> 8) + 0x400]
^ table[(byte)(high) + 0x300]
^ table[(byte)(high >>= 8) + 0x200]
^ table[(byte)(high >>= 8) + 0x100]
^ table[/*(byte)*/(high >> 8) + 0x000];
}
}
while (count-- != 0)
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
value = crc;
}
static public int Compute(byte[] data, int offset, int count)
{
var crc = new OptimizedCRC();
crc.Update(data, offset, count);
return crc.Value;
}
static public int Compute(byte[] data)
{
return Compute(data, 0, data.Length);
}
}
}

View File

@@ -1,302 +0,0 @@
/*
* Copyright (c) 2012-2015 Eugene Larchenko (el6345@gmail.com)
* This code is licensed under the Microsoft Public License (MS-PL).
* See the file LICENSE_MSPL for the license details.
*/
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
namespace CRC32
{
public class ParallelCRC
{
private const uint kPoly = 0xEDB88320;
private const uint kInit = 0xFFFFFFFF;
private const int NUM_TABLES = 8;
private static readonly uint[] Table;
private const int ThreadCost = 512 * 1024;
private static readonly int ProcessorCount = Environment.ProcessorCount;
static ParallelCRC()
{
unchecked
{
Table = new uint[256 * NUM_TABLES];
int i;
for (i = 0; i < 256; i++)
{
uint r = (uint)i;
for (int j = 0; j < 8; j++)
r = (r >> 1) ^ (kPoly & ~((r & 1) - 1));
Table[i] = r;
}
for (; i < 256 * NUM_TABLES; i++)
{
uint r = Table[i - 256];
Table[i] = Table[r & 0xFF] ^ (r >> 8);
}
}
}
private uint value;
public ParallelCRC()
{
Init();
}
/// <summary>
/// Reset CRC
/// </summary>
public void Init()
{
value = kInit;
}
public int Value
{
get { return (int)~value; }
}
public void Update(byte[] data, int offset, int count)
{
new ArraySegment<byte>(data, offset, count); // check arguments
// quick elimination
if (count <= ThreadCost || ProcessorCount <= 1)
{
value = ProcessBlock(value, data, offset, count);
return;
}
// choose optimal number of threads to use
int threadCount = ProcessorCount;
L0:
int bytesPerThread = (count + threadCount - 1) / threadCount;
if (bytesPerThread < (ThreadCost >> 1))
{
threadCount--;
goto L0;
}
// create jobs chain
// threadCount >= 2
Job? lastJob = null;
while (count > bytesPerThread)
{
var job = new Job(new ArraySegment<byte>(data, offset, bytesPerThread), this, lastJob);
ThreadPool.QueueUserWorkItem(job.Start);
offset += bytesPerThread;
count -= bytesPerThread;
lastJob = job;
}
// lastJob != null
var lastBlockCRC = ProcessBlock(kInit, data, offset, count);
lastJob?.WaitAndDispose();
value = Combine(value, lastBlockCRC, count);
}
private static uint ProcessBlock(uint crc, byte[] data, int offset, int count)
{
/*
* A copy of OptimizedCRC.cs
*/
if (count < 0) throw new ArgumentOutOfRangeException("count");
if (count == 0) return crc;
var table = ParallelCRC.Table;
for (; (offset & 7) != 0 && count != 0; count--)
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
if (count >= 8)
{
int end = (count - 8) & ~7;
count -= end;
end += offset;
while (offset != end)
{
crc ^= (uint)(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) + (data[offset + 3] << 24));
uint high = (uint)(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) + (data[offset + 7] << 24));
offset += 8;
crc = table[(byte)crc + 0x700]
^ table[(byte)(crc >>= 8) + 0x600]
^ table[(byte)(crc >>= 8) + 0x500]
^ table[/*(byte)*/(crc >> 8) + 0x400]
^ table[(byte)(high) + 0x300]
^ table[(byte)(high >>= 8) + 0x200]
^ table[(byte)(high >>= 8) + 0x100]
^ table[/*(byte)*/(high >> 8) + 0x000];
}
}
while (count-- != 0)
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
return crc;
}
static public int Compute(byte[] data, int offset, int count)
{
var crc = new ParallelCRC();
crc.Update(data, offset, count);
return crc.Value;
}
static public int Compute(byte[] data)
{
return Compute(data, 0, data.Length);
}
#region Combining
// Copyright (c) 2011 Dino Chiesa.
// This module is (refactored) part of DotNetZip, a zipfile class library.
// This code is licensed under the Microsoft Public License.
// See the file LICENSE_MSPL for the license details.
// More info on: http://dotnetzip.codeplex.com
/// <summary>
/// Combine sums of two segments.
/// This function is thread-safe.
/// </summary>
private static uint Combine(uint crc1, uint crc2, int length2)
{
// Note: this function is thread-safe even though it references static fields
if (length2 <= 0) return crc1;
if (crc1 == kInit) return crc2;
if (even_cache == null)
{
Prepare_even_odd_Cache();
}
uint[] even = even_cache?.ToArray() ?? [];
uint[] odd = odd_cache?.ToArray() ?? [];
crc1 = ~crc1;
crc2 = ~crc2;
uint len2 = (uint)length2;
// apply len2 zeros to crc1 (first square will put the operator for one
// zero byte, eight zero bits, in even)
do
{
// apply zeros operator for this bit of len2
gf2_matrix_square(even, odd);
if ((len2 & 1) != 0) crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
if (len2 == 0) break;
// another iteration of the loop with odd and even swapped
gf2_matrix_square(odd, even);
if ((len2 & 1) != 0) crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
} while (len2 != 0);
crc1 ^= crc2;
return ~crc1;
}
private static uint[]? even_cache = null;
private static uint[]? odd_cache;
private static void Prepare_even_odd_Cache()
{
var even = new uint[32]; // even-power-of-two zeros operator
var odd = new uint[32]; // odd-power-of-two zeros operator
// put operator for one zero bit in odd
odd[0] = kPoly; // the CRC-32 polynomial
for (int i = 1; i < 32; i++) odd[i] = 1U << (i - 1);
// put operator for two zero bits in even
gf2_matrix_square(even, odd);
// put operator for four zero bits in odd
gf2_matrix_square(odd, even);
odd_cache = odd;
even_cache = even;
}
/// <param name="matrix">will not be modified</param>
private static uint gf2_matrix_times(uint[] matrix, uint vec)
{
uint sum = 0;
int i = 0;
while (vec != 0)
{
if ((vec & 1) != 0) sum ^= matrix[i];
vec >>= 1;
i++;
}
return sum;
}
/// <param name="square">this array will be modified!</param>
/// <param name="mat">will not be modified</param>
private static void gf2_matrix_square(uint[] square, uint[] mat)
{
for (int i = 0; i < 32; i++)
square[i] = gf2_matrix_times(mat, mat[i]);
}
#endregion Combining
class Job
{
private ArraySegment<byte> data;
private Job? previousJob;
private ParallelCRC accumulator;
private ManualResetEvent? finished;
public Job(ArraySegment<byte> data, ParallelCRC accumulator, Job? previousJob)
{
this.data = data;
this.accumulator = accumulator;
this.previousJob = previousJob;
this.finished = new ManualResetEvent(false);
}
public void Start(object? arg)
{
var crc = ProcessBlock(kInit, data.Array!, data.Offset, data.Count);
if (previousJob != null) previousJob.WaitAndDispose();
accumulator.value = Combine(accumulator.value, crc, data.Count);
finished?.Set();
}
public void WaitAndDispose()
{
finished?.WaitOne();
Dispose();
}
public void Dispose()
{
if (finished != null) finished.Close();
finished = null;
}
}
}
}

View File

@@ -1,80 +0,0 @@
using System;
using System.IO;
using System.Threading;
namespace Compress.ThreadReaders
{
internal sealed class ThreadLoadBuffer : IDisposable
{
private readonly AutoResetEvent _waitEvent;
private readonly AutoResetEvent _outEvent;
private readonly Thread _tWorker;
private byte[]? _buffer;
private int _size;
private readonly Stream _ds;
private bool _finished;
public bool errorState;
public int SizeRead;
public ThreadLoadBuffer(Stream ds)
{
_waitEvent = new AutoResetEvent(false);
_outEvent = new AutoResetEvent(false);
_finished = false;
_ds = ds;
errorState = false;
_tWorker = new Thread(MainLoop);
_tWorker.Start();
}
public void Dispose()
{
_waitEvent.Close();
_outEvent.Close();
}
private void MainLoop()
{
while (true)
{
_waitEvent.WaitOne();
if (_finished)
{
break;
}
try
{
if (_buffer != null)
SizeRead = _ds.Read(_buffer, 0, _size);
}
catch (Exception)
{
errorState = true;
}
_outEvent.Set();
}
}
public void Trigger(byte[] buffer, int size)
{
_buffer = buffer;
_size = size;
_waitEvent.Set();
}
public void Wait()
{
_outEvent.WaitOne();
}
public void Finish()
{
_finished = true;
_waitEvent.Set();
_tWorker.Join();
}
}
}

View File

@@ -0,0 +1,38 @@
namespace SabreTools.Hashing.Crc
{
internal static class BitOperations
{
/// <summary>
/// Reverse the endianness of a value
/// </summary>
public static ulong ReverseBits(ulong value, int bitWidth)
{
ulong reverse = 0;
for (int i = 0; i < bitWidth; i++)
{
reverse <<= 1;
reverse |= value & 1;
value >>= 1;
}
return reverse;
}
/// <summary>
/// Clamp a value to a certain bit width and convert to a byte array
/// </summary>
public static byte[] ClampValueToBytes(ulong value, int bitWidth)
{
value &= ulong.MaxValue >> (64 - bitWidth);
byte[] bytes = new byte[(bitWidth + 7) / 8];
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = (byte)value;
value >>= 8;
}
return bytes;
}
}
}

View File

@@ -0,0 +1,60 @@
namespace SabreTools.Hashing.Crc
{
/// <see href="https://reveng.sourceforge.io/crc-catalogue/all.htm#crc.legend"/>
internal class CrcDefinition
{
/// <summary>
/// The number of bit cells in the linear feedback shift register;
/// the degree of the generator polynomial, less one.
/// </summary>
public int Width { get; set; }
/// <summary>
/// The generator polynomial that sets the feedback tap positions of
/// the shift register. poly is written in the hexadecimal, direct
/// notation found in MSB-first code. The least significant bit
/// corresponds to the inward end of the shift register, and is always
/// set. The highest-order term is omitted.
/// </summary>
public ulong Poly { get; set; }
/// <summary>
/// The settings of the bit cells at the start of each calculation,
/// before reading the first message bit. init is written in the
/// hexadecimal, direct notation found in MSB-first code. The least
/// significant bit corresponds to the inward end of the shift register.
/// </summary>
public ulong Init { get; set; }
/// <summary>
/// If equal to false, specifies that the characters of the message
/// are read bit-by-bit, most significant bit (MSB) first; if equal to
/// true, the characters are read bit-by-bit, least significant bit (LSB)
/// first. Each sampled message bit is then XORed with the bit being
/// simultaneously shifted out of the register at the most significant
/// end, and the result is passed to the feedback taps.
/// </summary>
public bool ReflectIn { get; set; }
/// <summary>
/// If equal to false, specifies that the contents of the register after
/// reading the last message bit are unreflected before presentation;
/// if equal to true, it specifies that they are reflected,
/// character-by-character, before presentation. For the purpose of this
/// definition, the reflection is performed by swapping the content of
/// each cell with that of the cell an equal distance from the opposite
/// end of the register; the characters of the CRC are then true images
/// of parts of the reflected register, the character containing the
/// original MSB always appearing first.
/// </summary>
public bool ReflectOut { get; set; }
/// <summary>
/// The XOR value applied to the contents of the register after the last
/// message bit has been read and after the optional reflection. xorout
/// is written in hexadecimal notation, having the same endianness as
/// the CRC such that its true image appears in the characters of the CRC.
/// </summary>
public ulong XorOut { get; set; }
}
}

View File

@@ -0,0 +1,69 @@
using System;
namespace SabreTools.Hashing.Crc
{
internal class CrcRunner
{
/// <summary>
/// Definition used to create the runner
/// </summary>
private readonly CrcDefinition _definition;
/// <summary>
/// Table used for calculation steps
/// </summary>
private readonly CrcTable _table;
/// <summary>
/// The current value of the hash
/// </summary>
private ulong _hash;
public CrcRunner(CrcDefinition def)
{
// Check for a valid bit width
if (def.Width < 0 || def.Width > 64)
throw new ArgumentOutOfRangeException(nameof(def));
_definition = def;
_table = new CrcTable(def);
_hash = def.Init;
}
/// <summary>
/// Reset the internal hashing state
/// </summary>
public void Reset()
{
_hash = _definition.Init;
}
/// <summary>
/// Hash a block of data and append it to the existing hash
/// </summary>
/// <param name="data">Byte array representing the data</param>
/// <param name="offset">Offset in the byte array to include</param>
/// <param name="length">Length of the data to hash</param>
public void TransformBlock(byte[] data, int offset, int length)
=> _table.TransformBlock(ref _hash, data, offset, length);
/// <summary>
/// Finalize the hash and return as a byte array
/// </summary>
public byte[] Finalize()
{
// Create a copy of the hash
ulong localHash = _hash;
// Handle mutual reflection
if (_definition.ReflectIn ^ _definition.ReflectOut)
localHash = BitOperations.ReverseBits(localHash, _definition.Width);
// Handle XOR
localHash ^= _definition.XorOut;
// Process the value and return
return BitOperations.ClampValueToBytes(localHash, _definition.Width);
}
}
}

View File

@@ -0,0 +1,230 @@
namespace SabreTools.Hashing.Crc
{
internal class CrcTable
{
/// <summary>
/// Indicates if CRC should be processed bitwise instead of bytewise
/// </summary>
private readonly bool _processBitwise;
/// <summary>
/// Number of bits to process at a time
/// </summary>
private readonly int _processBits;
/// <summary>
/// Bit shift based on the CRC width
/// </summary>
private readonly int _bitShift;
/// <summary>
/// Bit mask based on the CRC width
/// </summary>
private readonly ulong _bitMask;
/// <summary>
/// Mapping table
/// </summary>
private readonly ulong[,] _table;
/// <summary>
/// Definition used to build the table
/// </summary>
private readonly CrcDefinition _definition;
/// <summary>
/// Number of slices in the optimized table
/// </summary>
private const int SliceCount = 8;
public CrcTable(CrcDefinition def)
{
// Set the accessible fields
_definition = def;
_processBitwise = _definition.Width < 8;
_processBits = _processBitwise ? 1 : 8;
_bitShift = _definition.Width - _processBits;
_bitMask = 1UL << (_definition.Width - 1);
// Initialize the internal
_table = new ulong[SliceCount, 1 << _processBits];
// Build the standard table
for (int i = 0; i < 1 << _processBits; i++)
{
// Get the starting value for this index
ulong point = (ulong)i;
if (!_processBitwise && def.ReflectIn)
point = BitOperations.ReverseBits(point, _processBits);
// Shift to account for storage
point <<= _definition.Width - _processBits;
// Accumulate the value
for (int j = 0; j < 8; j++)
{
if ((point & _bitMask) > 0)
point = (point << 1) ^ def.Poly;
else
point <<= 1;
}
// Reflect if necessary
if (def.ReflectIn)
point = BitOperations.ReverseBits(point, def.Width);
// Shift back to account for storage
point &= ulong.MaxValue >> (64 - def.Width);
// Assign to both tables
_table[0, i] = point;
}
// Skip building the optimized table for bitwise processing
if (_processBitwise)
return;
// Build the optimized table for non-bitwise processing
for (int i = 1; i < SliceCount; i++)
{
// Build each slice from the previous
for (int j = 0; j < 1 << _processBits; j++)
{
ulong last = _table[i - 1, j];
if (_definition.ReflectIn)
_table[i, j] = (last >> _processBits) ^ _table[0, (byte)last];
else
_table[i, j] = (last << _processBits) ^ _table[0, (byte)(last >> _bitShift)];
}
}
}
/// <summary>
/// Hash a block of data and append it to the existing hash
/// </summary>
/// <param name="hash">Current hash value, updated on run</param>
/// <param name="data">Byte array representing the data</param>
/// <param name="offset">Offset in the byte array to include</param>
/// <param name="length">Length of the data to hash</param>
public void TransformBlock(ref ulong hash, byte[] data, int offset, int length)
{
// Empty data just returns
if (data.Length == 0)
return;
// Check for valid offset and length
if (offset > data.Length)
throw new System.ArgumentOutOfRangeException(nameof(offset));
else if (offset + length > data.Length)
throw new System.ArgumentOutOfRangeException(nameof(length));
// Try transforming fast first
if (TransformBlockFast(ref hash, data, offset, length))
return;
// Process the data byte-wise
for (int i = offset; i < offset + length; i++)
{
PerformChecksumStep(ref hash, data, i);
}
}
/// <summary>
/// Perform a single checksum step
/// </summary>
/// <param name="hash">Current hash value, updated on run</param>
/// <param name="data">Byte array representing the data</param>
/// <param name="offset">Offset in the data to process</param>
private void PerformChecksumStep(ref ulong hash, byte[] data, int offset)
{
// Per-bit processing
if (_processBitwise)
{
for (int b = 0; b < 8; b++)
{
if (_definition.ReflectIn)
hash = (hash >> _processBits) ^ _table[0, (byte)(hash & 1) ^ ((byte)(data[offset] >> b) & 1)];
else
hash = (hash << _processBits) ^ _table[0, (byte)((hash >> _bitShift) & 1) ^ ((byte)(data[offset] >> (7 - b)) & 1)];
}
}
// Per-byte processing
else
{
if (_definition.ReflectIn)
hash = (hash >> _processBits) ^ _table[0, (byte)hash ^ data[offset]];
else
hash = (hash << _processBits) ^ _table[0, ((byte)(hash >> _bitShift)) ^ data[offset]];
}
}
/// <summary>
/// Perform an optimized transform step
/// </summary>
private bool TransformBlockFast(ref ulong hash, byte[] data, int offset, int length)
{
// Bitwise transformations are not optimized
if (_processBitwise)
return false;
// Check for optimizable transformations
if (_definition.Width == 32 && _definition.ReflectIn)
{
TransformBlockFast32Reflect(ref hash, data, offset, length);
return true;
}
return false;
}
/// <summary>
/// Optimized transformation for 32-bit CRC with reflection
/// </summary>
private void TransformBlockFast32Reflect(ref ulong hash, byte[] data, int offset, int length)
{
// Process on a copy of the hash
ulong local = hash;
// Process aligned data
if (length > 8)
{
long end = offset + (length & ~(uint)7);
length &= 7;
while (offset < end)
{
ulong low = local ^ (uint)(
(data[offset + 0] )
+ (data[offset + 1] << 8 )
+ (data[offset + 2] << 16)
+ (data[offset + 3] << 24));
ulong high = (uint)(
+ (data[offset + 4] << 32)
+ (data[offset + 5] << 40)
+ (data[offset + 6] << 48)
+ (data[offset + 7] << 56));
offset += 8;
local = _table[7, (byte)(low )]
^ _table[6, (byte)(low >> 8 )]
^ _table[5, (byte)(low >> 16 )]
^ _table[4, (byte)(low >> 24 )]
^ _table[3, (byte)(high )]
^ _table[2, (byte)(high >> 8 )]
^ _table[1, (byte)(high >> 16)]
^ _table[0, (byte)(high >> 24)];
}
}
// Process unaligned data
while (length-- != 0)
{
PerformChecksumStep(ref local, data, offset++);
}
// Assign the new hash value
hash = local;
}
}
}

View File

@@ -0,0 +1,793 @@
namespace SabreTools.Hashing.Crc
{
/// <see href="https://reveng.sourceforge.io/crc-catalogue/all.htm#crc.legend"/>
internal static class StandardDefinitions
{
#region CRC-16
/// <summary>
/// CRC-16/ARC [ARC, CRC-16, CRC-16/LHA, CRC-IBM]
/// </summary>
public static readonly CrcDefinition CRC16_ARC = new()
{
Width = 16,
Poly = 0x8005,
Init = 0x0000,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/CDMA2000
/// </summary>
public static readonly CrcDefinition CRC16_CDMA2000 = new()
{
Width = 16,
Poly = 0xc867,
Init = 0xffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/CMS
/// </summary>
public static readonly CrcDefinition CRC16_CMS = new()
{
Width = 16,
Poly = 0x8005,
Init = 0xffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/DDS-110
/// </summary>
public static readonly CrcDefinition CRC16_DDS110 = new()
{
Width = 16,
Poly = 0x8005,
Init = 0x800d,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/DECT-R [R-CRC-16]
/// </summary>
public static readonly CrcDefinition CRC16_DECTR = new()
{
Width = 16,
Poly = 0x0589,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0001,
};
/// <summary>
/// CRC-16/DECT-X [X-CRC-16]
/// </summary>
public static readonly CrcDefinition CRC16_DECTX = new()
{
Width = 16,
Poly = 0x0589,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/DNP
/// </summary>
public static readonly CrcDefinition CRC16_DNP = new()
{
Width = 16,
Poly = 0x3d65,
Init = 0x0000,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffff,
};
/// <summary>
/// CRC-16/EN-13757
/// </summary>
public static readonly CrcDefinition CRC16_EN13757 = new()
{
Width = 16,
Poly = 0x3d65,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffff,
};
/// <summary>
/// CRC-16/GENIBUS [CRC-16/DARC, CRC-16/EPC, CRC-16/EPC-C1G2, CRC-16/I-CODE]
/// </summary>
public static readonly CrcDefinition CRC16_GENIBUS = new()
{
Width = 16,
Poly = 0x1021,
Init = 0xffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffff,
};
/// <summary>
/// CRC-16/GSM
/// </summary>
public static readonly CrcDefinition CRC16_GSM = new()
{
Width = 16,
Poly = 0x1021,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffff,
};
/// <summary>
/// CRC-16/IBM-3740 [CRC-16/AUTOSAR, CRC-16/CCITT-FALSE]
/// </summary>
public static readonly CrcDefinition CRC16_IBM3740 = new()
{
Width = 16,
Poly = 0x1021,
Init = 0xffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/IBM-SDLC [CRC-16/ISO-HDLC, CRC-16/ISO-IEC-14443-3-B, CRC-16/X-25, CRC-B, X-25]
/// </summary>
public static readonly CrcDefinition CRC16_IBMSDLC = new()
{
Width = 16,
Poly = 0x1021,
Init = 0xffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffff,
};
/// <summary>
/// CRC-16/ISO-IEC-14443-3-A [CRC-A]
/// </summary>
public static readonly CrcDefinition CRC16_ISOIEC144433A = new()
{
Width = 16,
Poly = 0x1021,
Init = 0xc6c6,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/KERMIT [CRC-16/BLUETOOTH, CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-16/V-41-LSB, CRC-CCITT, KERMIT]
/// </summary>
public static readonly CrcDefinition CRC16_KERMIT = new()
{
Width = 16,
Poly = 0x1021,
Init = 0x0000,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/LJ1200
/// </summary>
public static readonly CrcDefinition CRC16_LJ1200 = new()
{
Width = 16,
Poly = 0x6f63,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/M17
/// </summary>
public static readonly CrcDefinition CRC16_M17 = new()
{
Width = 16,
Poly = 0x5935,
Init = 0xffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/MAXIM-DOW [CRC-16/MAXIM]
/// </summary>
public static readonly CrcDefinition CRC16_MAXIMDOW = new()
{
Width = 16,
Poly = 0x8005,
Init = 0x0000,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffff,
};
/// <summary>
/// CRC-16/MCRF4XX
/// </summary>
public static readonly CrcDefinition CRC16_MCRF4XX = new()
{
Width = 16,
Poly = 0x1021,
Init = 0xffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/MODBUS [MODBUS]
/// </summary>
public static readonly CrcDefinition CRC16_MODBUS = new()
{
Width = 16,
Poly = 0x8005,
Init = 0xffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/NRSC-5
/// </summary>
public static readonly CrcDefinition CRC16_NRSC5 = new()
{
Width = 16,
Poly = 0x080b,
Init = 0xffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/OPENSAFETY-A
/// </summary>
public static readonly CrcDefinition CRC16_OPENSAFETYA = new()
{
Width = 16,
Poly = 0x5935,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/OPENSAFETY-B
/// </summary>
public static readonly CrcDefinition CRC16_OPENSAFETYB = new()
{
Width = 16,
Poly = 0x755b,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/PROFIBUS [CRC-16/IEC-61158-2]
/// </summary>
public static readonly CrcDefinition CRC16_PROFIBUS = new()
{
Width = 16,
Poly = 0x1dcf,
Init = 0xffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffff,
};
/// <summary>
/// CRC-16/RIELLO
/// </summary>
public static readonly CrcDefinition CRC16_RIELLO = new()
{
Width = 16,
Poly = 0x1021,
Init = 0xb2aa,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/SPI-FUJITSU [CRC-16/AUG-CCITT]
/// </summary>
public static readonly CrcDefinition CRC16_SPIFUJITSU = new()
{
Width = 16,
Poly = 0x1021,
Init = 0x1d0f,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/T10-DIF
/// </summary>
public static readonly CrcDefinition CRC16_T10DIF = new()
{
Width = 16,
Poly = 0x8bb7,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/TELEDISK
/// </summary>
public static readonly CrcDefinition CRC16_TELEDISK = new()
{
Width = 16,
Poly = 0xa097,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/TMS37157
/// </summary>
public static readonly CrcDefinition CRC16_TMS37157 = new()
{
Width = 16,
Poly = 0x1021,
Init = 0x89ec,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/UMTS [CRC-16/BUYPASS, CRC-16/VERIFONE]
/// </summary>
public static readonly CrcDefinition CRC16_UMTS = new()
{
Width = 16,
Poly = 0x8005,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
/// <summary>
/// CRC-16/USB
/// </summary>
public static readonly CrcDefinition CRC16_USB = new()
{
Width = 16,
Poly = 0x8005,
Init = 0xffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffff,
};
/// <summary>
/// CRC-16/XMODEM [CRC-16/ACORN, CRC-16/LTE, CRC-16/V-41-MSB, XMODEM, ZMODEM]
/// </summary>
public static readonly CrcDefinition CRC16_XMODEM = new()
{
Width = 16,
Poly = 0x1021,
Init = 0x0000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000,
};
#endregion
#region CRC-24
/// <summary>
/// CRC-24/BLE
/// </summary>
public static readonly CrcDefinition CRC24_BLE = new()
{
Width = 24,
Poly = 0x00065b,
Init = 0x555555,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x000000,
};
/// <summary>
/// CRC-24/FLEXRAY-A
/// </summary>
public static readonly CrcDefinition CRC24_FLEXRAYA = new()
{
Width = 24,
Poly = 0x5d6dcb,
Init = 0xfedcba,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x000000,
};
/// <summary>
/// CRC-24/FLEXRAY-B
/// </summary>
public static readonly CrcDefinition CRC24_FLEXRAYB = new()
{
Width = 24,
Poly = 0x5d6dcb,
Init = 0xabcdef,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x000000,
};
/// <summary>
/// CRC-24/INTERLAKEN
/// </summary>
public static readonly CrcDefinition CRC24_INTERLAKEN = new()
{
Width = 24,
Poly = 0x328b63,
Init = 0xffffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffffff,
};
/// <summary>
/// CRC-24/LTE-A
/// </summary>
public static readonly CrcDefinition CRC24_LTEA = new()
{
Width = 24,
Poly = 0x864cfb,
Init = 0x000000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x000000,
};
/// <summary>
/// CRC-24/LTE-B
/// </summary>
public static readonly CrcDefinition CRC24_LTEB = new()
{
Width = 24,
Poly = 0x800063,
Init = 0x000000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x000000,
};
/// <summary>
/// CRC-24/OPENPGP
/// </summary>
public static readonly CrcDefinition CRC24_OPENPGP = new()
{
Width = 24,
Poly = 0x864cfb,
Init = 0xb704ce,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x000000,
};
/// <summary>
/// CRC-24/OS-9
/// </summary>
public static readonly CrcDefinition CRC24_OS9 = new()
{
Width = 24,
Poly = 0x800063,
Init = 0xffffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffffff,
};
#endregion
#region CRC-32
/// <summary>
/// CRC-32/AIXM
/// </summary>
public static readonly CrcDefinition CRC32_AIXM = new()
{
Width = 32,
Poly = 0x814141ab,
Init = 0x00000000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x00000000,
};
/// <summary>
/// CRC-32/AUTOSAR
/// </summary>
public static readonly CrcDefinition CRC32_AUTOSAR = new()
{
Width = 32,
Poly = 0xf4acfb13,
Init = 0xffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffffffff,
};
/// <summary>
/// CRC-32/BASE91-D
/// </summary>
public static readonly CrcDefinition CRC32_BASE91D = new()
{
Width = 32,
Poly = 0xa833982b,
Init = 0xffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffffffff,
};
/// <summary>
/// CRC-32/BZIP2
/// </summary>
public static readonly CrcDefinition CRC32_BZIP2 = new()
{
Width = 32,
Poly = 0x04c11db7,
Init = 0xffffffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffffffff,
};
/// <summary>
/// CRC-32/CD-ROM-EDC
/// </summary>
public static readonly CrcDefinition CRC32_CDROMEDC = new()
{
Width = 32,
Poly = 0x8001801b,
Init = 0x00000000,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x00000000,
};
/// <summary>
/// CRC-32/CKSUM
/// </summary>
public static readonly CrcDefinition CRC32_CKSUM = new()
{
Width = 32,
Poly = 0x04c11db7,
Init = 0x00000000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffffffff,
};
/// <summary>
/// CRC-32/ISCSI
/// </summary>
public static readonly CrcDefinition CRC32_ISCSI = new()
{
Width = 32,
Poly = 0x1edc6f41,
Init = 0xffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffffffff,
};
/// <summary>
/// CRC-32/ISO-HDLC
/// </summary>
public static readonly CrcDefinition CRC32_ISOHDLC = new()
{
Width = 32,
Poly = 0x04c11db7,
Init = 0xffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffffffff,
};
/// <summary>
/// CRC-32/JAMCRC
/// </summary>
public static readonly CrcDefinition CRC32_JAMCRC = new()
{
Width = 32,
Poly = 0x04c11db7,
Init = 0xffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x00000000,
};
/// <summary>
/// CRC-32/MEF
/// </summary>
public static readonly CrcDefinition CRC32_MEF = new()
{
Width = 32,
Poly = 0x741b8cd7,
Init = 0xffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x00000000,
};
/// <summary>
/// CRC-32/MPEG-2
/// </summary>
public static readonly CrcDefinition CRC32_MPEG2 = new()
{
Width = 32,
Poly = 0x04c11db7,
Init = 0xffffffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x00000000,
};
/// <summary>
/// CRC-32/XFER
/// </summary>
public static readonly CrcDefinition CRC32_XFER = new()
{
Width = 32,
Poly = 0x000000af,
Init = 0x00000000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x00000000,
};
#endregion
#region CRC-40
/// <summary>
/// CRC-40/GSM
/// </summary>
public static readonly CrcDefinition CRC40_GSM = new()
{
Width = 40,
Poly = 0x0004820009,
Init = 0x0000000000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffffffffff,
};
#endregion
#region CRC-64
/// <summary>
/// CRC-64/ECMA-182
/// </summary>
public static readonly CrcDefinition CRC64_ECMA182 = new()
{
Width = 64,
Poly = 0x42f0e1eba9ea3693,
Init = 0x0000000000000000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x0000000000000000,
};
/// <summary>
/// CRC-64/GO-ISO
/// </summary>
public static readonly CrcDefinition CRC64_GOISO = new()
{
Width = 64,
Poly = 0x000000000000001b,
Init = 0xffffffffffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffffffffffffffff,
};
/// <summary>
/// CRC-64/MS
/// </summary>
public static readonly CrcDefinition CRC64_MS = new()
{
Width = 64,
Poly = 0x259c84cba6426349,
Init = 0xffffffffffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000000000000000,
};
/// <summary>
/// CRC-64/NVME
/// </summary>
public static readonly CrcDefinition CRC64_NVME = new()
{
Width = 64,
Poly = 0xad93d23594c93659,
Init = 0xffffffffffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffffffffffffffff,
};
/// <summary>
/// CRC-64/REDIS
/// </summary>
public static readonly CrcDefinition CRC64_REDIS = new()
{
Width = 64,
Poly = 0xad93d23594c935a9,
Init = 0x0000000000000000,
ReflectIn = true,
ReflectOut = true,
XorOut = 0x0000000000000000,
};
/// <summary>
/// CRC-64/WE
/// </summary>
public static readonly CrcDefinition CRC64_WE = new()
{
Width = 64,
Poly = 0x42f0e1eba9ea3693,
Init = 0xffffffffffffffff,
ReflectIn = false,
ReflectOut = false,
XorOut = 0xffffffffffffffff,
};
/// <summary>
/// CRC-64/XZ
/// </summary>
public static readonly CrcDefinition CRC64_XZ = new()
{
Width = 64,
Poly = 0x42f0e1eba9ea3693,
Init = 0xffffffffffffffff,
ReflectIn = true,
ReflectOut = true,
XorOut = 0xffffffffffffffff,
};
#endregion
}
}

View File

@@ -4,7 +4,6 @@ using System.IO;
#if NET40_OR_GREATER || NETCOREAPP
using System.Threading.Tasks;
#endif
using Compress.ThreadReaders;
namespace SabreTools.Hashing
{
@@ -343,104 +342,24 @@ namespace SabreTools.Hashing
// Create the output dictionary
var hashDict = new Dictionary<HashType, string?>();
try
{
// Get a list of hashers to run over the buffer
var hashers = new Dictionary<HashType, HashWrapper>();
// Add hashers based on requested types
foreach (HashType hashType in hashTypes)
{
hashers[hashType] = new HashWrapper(hashType);
}
// Initialize the hashing helpers
var loadBuffer = new ThreadLoadBuffer(input);
int buffersize = 3 * 1024 * 1024;
byte[] buffer0 = new byte[buffersize];
byte[] buffer1 = new byte[buffersize];
/*
Please note that some of the following code is adapted from
RomVault. This is a modified version of how RomVault does
threaded hashing. As such, some of the terminology and code
is the same, though variable names and comments may have
been tweaked to better fit this code base.
*/
// Pre load the first buffer
long refsize = input.Length;
int next = refsize > buffersize ? buffersize : (int)refsize;
input.Read(buffer0, 0, next);
int current = next;
refsize -= next;
bool bufferSelect = true;
while (current > 0)
{
// Trigger the buffer load on the second buffer
next = refsize > buffersize ? buffersize : (int)refsize;
if (next > 0)
loadBuffer.Trigger(bufferSelect ? buffer1 : buffer0, next);
byte[] buffer = bufferSelect ? buffer0 : buffer1;
#if NET20 || NET35
// Run hashers sequentially on each chunk
foreach (var h in hashers)
{
h.Value.Process(buffer, 0, current);
}
#else
// Run hashers in parallel on each chunk
Parallel.ForEach(hashers, h => h.Value.Process(buffer, 0, current));
#endif
// Wait for the load buffer worker, if needed
if (next > 0)
loadBuffer.Wait();
// Setup for the next hashing step
current = next;
refsize -= next;
bufferSelect = !bufferSelect;
}
// Finalize all hashing helpers
loadBuffer.Finish();
#if NET20 || NET35
foreach (var h in hashers)
{
h.Value.Terminate();
}
#else
Parallel.ForEach(hashers, h => h.Value.Terminate());
#endif
// Get the results
foreach (var hasher in hashers)
{
hashDict[hasher.Key] = hasher.Value.CurrentHashString;
}
// Dispose of the hashers
loadBuffer.Dispose();
foreach (var hasher in hashers.Values)
{
hasher.Dispose();
}
return hashDict;
}
catch (IOException)
{
// Run the hashing
var hashers = GetStreamHashesInternal(input, hashTypes, leaveOpen);
if (hashers == null)
return null;
}
finally
// Get the results
foreach (var hasher in hashers)
{
if (!leaveOpen)
input.Dispose();
hashDict[hasher.Key] = hasher.Value.CurrentHashString;
}
// Dispose of the hashers
foreach (var hasher in hashers.Values)
{
hasher.Dispose();
}
return hashDict;
}
/// <summary>
@@ -449,11 +368,43 @@ namespace SabreTools.Hashing
/// <param name="input">Stream to hash</param>
/// <param name="hashTypes">Array of hash types to get from the file</param>
/// <returns>Dictionary containing hashes on success, null on error</returns>
private static Dictionary<HashType, byte[]?>? GetStreamHashArrays(Stream input, HashType[] hashTypes, bool leaveOpen = false)
public static Dictionary<HashType, byte[]?>? GetStreamHashArrays(Stream input, HashType[] hashTypes, bool leaveOpen = false)
{
// Create the output dictionary
var hashDict = new Dictionary<HashType, byte[]?>();
// Run the hashing
var hashers = GetStreamHashesInternal(input, hashTypes, leaveOpen);
if (hashers == null)
return null;
// Get the results
foreach (var hasher in hashers)
{
hashDict[hasher.Key] = hasher.Value.CurrentHashBytes;
}
// Dispose of the hashers
foreach (var hasher in hashers.Values)
{
hasher.Dispose();
}
return hashDict;
}
/// <summary>
/// Get hashes from an input stream
/// </summary>
/// <param name="input"></param>
/// <param name="hashTypes"></param>
/// <param name="leaveOpen"></param>
/// <returns></returns>
private static Dictionary<HashType, HashWrapper>? GetStreamHashesInternal(Stream input, HashType[] hashTypes, bool leaveOpen)
{
// Create the output dictionary
var hashDict = new Dictionary<HashType, string?>();
try
{
// Get a list of hashers to run over the buffer
@@ -465,83 +416,44 @@ namespace SabreTools.Hashing
hashers[hashType] = new HashWrapper(hashType);
}
// Initialize the hashing helpers
var loadBuffer = new ThreadLoadBuffer(input);
// Create the buffer for holding data
int buffersize = 3 * 1024 * 1024;
byte[] buffer0 = new byte[buffersize];
byte[] buffer1 = new byte[buffersize];
byte[] buffer = new byte[buffersize];
int lastRead;
/*
Please note that some of the following code is adapted from
RomVault. This is a modified version of how RomVault does
threaded hashing. As such, some of the terminology and code
is the same, though variable names and comments may have
been tweaked to better fit this code base.
*/
// Pre load the first buffer
long refsize = input.Length;
int next = refsize > buffersize ? buffersize : (int)refsize;
input.Read(buffer0, 0, next);
int current = next;
refsize -= next;
bool bufferSelect = true;
while (current > 0)
// Hash the input data in blocks
do
{
// Trigger the buffer load on the second buffer
next = refsize > buffersize ? buffersize : (int)refsize;
if (next > 0)
loadBuffer.Trigger(bufferSelect ? buffer1 : buffer0, next);
byte[] buffer = bufferSelect ? buffer0 : buffer1;
// Load the buffer and hold the number of bytes read
lastRead = input.Read(buffer, 0, buffersize);
if (lastRead == 0)
break;
#if NET20 || NET35
// Run hashers sequentially on each chunk
foreach (var h in hashers)
{
h.Value.Process(buffer, 0, current);
h.Value.Process(buffer, 0, lastRead);
}
#else
// Run hashers in parallel on each chunk
Parallel.ForEach(hashers, h => h.Value.Process(buffer, 0, current));
Parallel.ForEach(hashers, h => h.Value.Process(buffer, 0, lastRead));
#endif
// Wait for the load buffer worker, if needed
if (next > 0)
loadBuffer.Wait();
// Setup for the next hashing step
current = next;
refsize -= next;
bufferSelect = !bufferSelect;
}
while (lastRead > 0);
// Finalize all hashing helpers
loadBuffer.Finish();
#if NET20 || NET35
// Finalize all hashing helpers sequentially
foreach (var h in hashers)
{
h.Value.Terminate();
}
#else
// Finalize all hashing helpers in parallel
Parallel.ForEach(hashers, h => h.Value.Terminate());
#endif
// Get the results
foreach (var hasher in hashers)
{
hashDict[hasher.Key] = hasher.Value.CurrentHashBytes;
}
// Dispose of the hashers
loadBuffer.Dispose();
foreach (var hasher in hashers.Values)
{
hasher.Dispose();
}
return hashDict;
return hashers;
}
catch (IOException)
{

View File

@@ -17,51 +17,318 @@ namespace SabreTools.Hashing
BLAKE3,
#endif
// <summary>
/// CRC 16-bit checksum using the CCITT polynomial
/// <summary>
/// CRC 16-bit checksum
/// </summary>
CRC16_CCITT,
/// <remarks>Identical to <see cref="CRC16_ARC"/>
CRC16,
// <summary>
/// CRC 16-bit checksum using the IBM polynomial
/// <summary>
/// CRC 16-bit checksum (CRC-16/ARC [ARC, CRC-16, CRC-16/LHA, CRC-IBM])
/// </summary>
CRC16_IBM,
CRC16_ARC,
/// <summary>
/// CRC 16-bit checksum (CRC-16/CDMA2000)
/// </summary>
CRC16_CDMA2000,
/// <summary>
/// CRC 16-bit checksum (CRC-16/CMS)
/// </summary>
CRC16_CMS,
/// <summary>
/// CRC 16-bit checksum (CRC-16/DDS-110)
/// </summary>
CRC16_DDS110,
/// <summary>
/// CRC 16-bit checksum (CRC-16/DECT-R [R-CRC-16])
/// </summary>
CRC16_DECTR,
/// <summary>
/// CRC 16-bit checksum (CRC-16/DECT-X [X-CRC-16])
/// </summary>
CRC16_DECTX,
/// <summary>
/// CRC 16-bit checksum (CRC-16/DNP)
/// </summary>
CRC16_DNP,
/// <summary>
/// CRC 16-bit checksum (CRC-16/EN-13757)
/// </summary>
CRC16_EN13757,
/// <summary>
/// CRC 16-bit checksum (CRC-16/GENIBUS [CRC-16/DARC, CRC-16/EPC, CRC-16/EPC-C1G2, CRC-16/I-CODE])
/// </summary>
CRC16_GENIBUS,
/// <summary>
/// CRC 16-bit checksum (CRC-16/GSM)
/// </summary>
CRC16_GSM,
/// <summary>
/// CRC 16-bit checksum (CRC-16/IBM-3740 [CRC-16/AUTOSAR, CRC-16/CCITT-FALSE])
/// </summary>
CRC16_IBM3740,
/// <summary>
/// CRC 16-bit checksum (CRC-16/IBM-SDLC [CRC-16/ISO-HDLC, CRC-16/ISO-IEC-14443-3-B, CRC-16/X-25, CRC-B, X-25])
/// </summary>
CRC16_IBMSDLC,
/// <summary>
/// CRC 16-bit checksum (CRC-16/ISO-IEC-14443-3-A [CRC-A])
/// </summary>
//CRC16_ISOIEC144433A, // Disabled until incorrect hashes can be fixed
/// <summary>
/// CRC 16-bit checksum (CRC-16/KERMIT [CRC-16/BLUETOOTH, CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-16/V-41-LSB, CRC-CCITT, KERMIT])
/// </summary>
CRC16_KERMIT,
/// <summary>
/// CRC 16-bit checksum (CRC-16/LJ1200)
/// </summary>
CRC16_LJ1200,
/// <summary>
/// CRC 16-bit checksum (CRC-16/M17)
/// </summary>
CRC16_M17,
/// <summary>
/// CRC 16-bit checksum (CRC-16/MAXIM-DOW [CRC-16/MAXIM])
/// </summary>
CRC16_MAXIMDOW,
/// <summary>
/// CRC 16-bit checksum (CRC-16/MCRF4XX)
/// </summary>
CRC16_MCRF4XX,
/// <summary>
/// CRC 16-bit checksum (CRC-16/MODBUS [MODBUS])
/// </summary>
CRC16_MODBUS,
/// <summary>
/// CRC 16-bit checksum (CRC-16/NRSC-5)
/// </summary>
CRC16_NRSC5,
/// <summary>
/// CRC 16-bit checksum (CRC-16/OPENSAFETY-A)
/// </summary>
CRC16_OPENSAFETYA,
/// <summary>
/// CRC 16-bit checksum (CRC-16/OPENSAFETY-B)
/// </summary>
CRC16_OPENSAFETYB,
/// <summary>
/// CRC 16-bit checksum (CRC-16/PROFIBUS [CRC-16/IEC-61158-2])
/// </summary>
CRC16_PROFIBUS,
/// <summary>
/// CRC 16-bit checksum (CRC-16/RIELLO)
/// </summary>
//CRC16_RIELLO, // Disabled until incorrect hashes can be fixed
/// <summary>
/// CRC 16-bit checksum (CRC-16/SPI-FUJITSU [CRC-16/AUG-CCITT])
/// </summary>
CRC16_SPIFUJITSU,
/// <summary>
/// CRC 16-bit checksum (CRC-16/T10-DIF)
/// </summary>
CRC16_T10DIF,
/// <summary>
/// CRC 16-bit checksum (CRC-16/TELEDISK)
/// </summary>
CRC16_TELEDISK,
/// <summary>
/// CRC 16-bit checksum (CRC-16/TMS37157)
/// </summary>
//CRC16_TMS37157, // Disabled until incorrect hashes can be fixed
/// <summary>
/// CRC 16-bit checksum (CRC-16/UMTS [CRC-16/BUYPASS, CRC-16/VERIFONE])
/// </summary>
CRC16_UMTS,
/// <summary>
/// CRC 16-bit checksum (CRC-16/USB)
/// </summary>
CRC16_USB,
/// <summary>
/// CRC 16-bit checksum (CRC-16/XMODEM [CRC-16/ACORN, CRC-16/LTE, CRC-16/V-41-MSB, XMODEM, ZMODEM])
/// </summary>
CRC16_XMODEM,
/// <summary>
/// CRC 24-bit checksum (CRC-24/BLE)
/// </summary>
//CRC24_BLE, // Disabled until incorrect hashes can be fixed
/// <summary>
/// CRC 24-bit checksum (CRC-24/FLEXRAY-A)
/// </summary>
CRC24_FLEXRAYA,
/// <summary>
/// CRC 24-bit checksum (CRC-24/FLEXRAY-B)
/// </summary>
CRC24_FLEXRAYB,
/// <summary>
/// CRC 24-bit checksum (CRC-24/INTERLAKEN)
/// </summary>
CRC24_INTERLAKEN,
/// <summary>
/// CRC 24-bit checksum (CRC-24/LTE-A)
/// </summary>
CRC24_LTEA,
/// <summary>
/// CRC 24-bit checksum (CRC-24/LTE-B)
/// </summary>
CRC24_LTEB,
/// <summary>
/// CRC 24-bit checksum (CRC-24/OPENPGP)
/// </summary>
CRC24_OPENPGP,
/// <summary>
/// CRC 24-bit checksum (CRC-24/OS-9)
/// </summary>
CRC24_OS9,
/// <summary>
/// CRC 32-bit checksum
/// </summary>
/// <remarks>Same as CRC32_ISO in .NET Framework 4.5.2 and lower</remarks>
/// <remarks>Identical to <see cref="CRC32_ISOHDLC"/>
CRC32,
/// <summary>
/// CRC 32-bit checksum (ISO implementation)
/// CRC 32-bit checksum (CRC-32/AIXM)
/// </summary>
CRC32_ISO,
CRC32_AIXM,
/// <summary>
/// CRC 32-bit checksum (NaiveCRC implementation)
/// CRC 32-bit checksum (CRC-32/AUTOSAR)
/// </summary>
CRC32_Naive,
CRC32_AUTOSAR,
/// <summary>
/// CRC 32-bit checksum (OptimizedCRC implementation)
/// CRC 32-bit checksum (CRC-32/BASE91-D)
/// </summary>
CRC32_Optimized,
CRC32_BASE91D,
/// <summary>
/// CRC 32-bit checksum (ParallelCRC implementation)
/// CRC 32-bit checksum (BZIP2)
/// </summary>
CRC32_Parallel,
CRC32_BZIP2,
/// <summary>
/// CRC 64-bit checksum (0x42F0E1EBA9EA3693 polynomial)
/// CRC 32-bit checksum (CRC-32/CD-ROM-EDC)
/// </summary>
CRC32_CDROMEDC,
/// <summary>
/// CRC 32-bit checksum (CRC-32/CKSUM)
/// </summary>
CRC32_CKSUM,
/// <summary>
/// CRC 32-bit checksum (CRC-32/ISCSI)
/// </summary>
CRC32_ISCSI,
/// <summary>
/// CRC 32-bit checksum (CRC-32/ISO-HDLC)
/// </summary>
CRC32_ISOHDLC,
/// <summary>
/// CRC 32-bit checksum (CRC-32/JAMCRC)
/// </summary>
CRC32_JAMCRC,
/// <summary>
/// CRC 32-bit checksum (CRC-32/MEF)
/// </summary>
CRC32_MEF,
/// <summary>
/// CRC 32-bit checksum (CRC-32/MPEG-2)
/// </summary>
CRC32_MPEG2,
/// <summary>
/// CRC 32-bit checksum (CRC-32/XFER)
/// </summary>
CRC32_XFER,
/// <summary>
/// CRC 40-bit checksum (CRC-40/GSM)
/// </summary>
CRC40_GSM,
/// <summary>
/// CRC 64-bit checksum
/// </summary>
/// <remarks>Identical to <see cref="CRC64_ECMA182"/>
CRC64,
/// <summary>
/// CRC 64-bit checksum (0xC96C5795D7870F42 polynomial)
/// CRC 64-bit checksum (CRC-64/ECMA-182, Microsoft implementation)
/// </summary>
CRC64_Reversed,
CRC64_ECMA182,
/// <summary>
/// CRC 64-bit checksum (CRC-64/GO-ISO)
/// </summary>
CRC64_GOISO,
/// <summary>
/// CRC 64-bit checksum (CRC-64/MS)
/// </summary>
CRC64_MS,
/// <summary>
/// CRC 64-bit checksum (CRC-64/NVME)
/// </summary>
CRC64_NVME,
/// <summary>
/// CRC 64-bit checksum (CRC-64/REDIS)
/// </summary>
CRC64_REDIS,
/// <summary>
/// CRC 64-bit checksum (CRC-64/WE)
/// </summary>
CRC64_WE,
/// <summary>
/// CRC 64-bit checksum (CRC-64/XZ)
/// </summary>
CRC64_XZ,
/// <summary>
/// John G. Fletcher's 16-bit checksum

View File

@@ -2,14 +2,13 @@ using System;
#if NET462_OR_GREATER || NETCOREAPP
using System.IO.Hashing;
#endif
using System.Linq;
using System.Security.Cryptography;
using Aaru.Checksums;
using Aaru.CommonTypes.Interfaces;
#if NET7_0_OR_GREATER
using Blake3;
#endif
using CRC32;
using SabreTools.Hashing.Crc;
namespace SabreTools.Hashing
{
@@ -23,11 +22,7 @@ namespace SabreTools.Hashing
/// <summary>
/// Hash type associated with the current state
/// </summary>
#if NETFRAMEWORK || NETCOREAPP3_1
public HashType HashType { get; private set; }
#else
public HashType HashType { get; init; }
#endif
public readonly HashType HashType;
/// <summary>
/// Current hash in bytes
@@ -36,22 +31,31 @@ namespace SabreTools.Hashing
{
get
{
return _hasher switch
switch (_hasher)
{
HashAlgorithm ha => ha.Hash,
IChecksum ic => ic.Final(),
NaiveCRC ncrc => BitConverter.GetBytes(ncrc.Value).Reverse().ToArray(),
case CrcRunner cr:
var crArr = cr.Finalize();
Array.Reverse(crArr);
return crArr;
case HashAlgorithm ha:
return ha.Hash;
case IChecksum ic:
return ic.Final();
#if NET462_OR_GREATER || NETCOREAPP
NonCryptographicHashAlgorithm ncha => ncha.GetCurrentHash().Reverse().ToArray(),
case NonCryptographicHashAlgorithm ncha:
var nchaArr = ncha.GetCurrentHash();
Array.Reverse(nchaArr);
return nchaArr;
#endif
OptimizedCRC ocrc => BitConverter.GetBytes(ocrc.Value).Reverse().ToArray(),
ParallelCRC pcrc => BitConverter.GetBytes(pcrc.Value).Reverse().ToArray(),
#if NET8_0_OR_GREATER
Shake128 s128 => s128.GetCurrentHash(32),
Shake256 s256 => s256.GetCurrentHash(64),
case Shake128 s128:
return s128.GetCurrentHash(32);
case Shake256 s256:
return s256.GetCurrentHash(64);
#endif
_ => null,
};
default:
return null;
}
}
}
@@ -80,11 +84,6 @@ namespace SabreTools.Hashing
/// <remarks>May be either a HashAlgorithm or NonCryptographicHashAlgorithm</remarks>
private object? _hasher;
/// <summary>
/// Non-reversed CRC-64 polynomial
/// </summary>
private const ulong CRC64_ECMA_POLY_NORMAL = 0x42F0E1EBA9EA3693;
#endregion
#region Constructors
@@ -95,7 +94,7 @@ namespace SabreTools.Hashing
/// <param name="hashType">Hash type to instantiate</param>
public HashWrapper(HashType hashType)
{
this.HashType = hashType;
HashType = hashType;
GetHasher();
}
@@ -107,32 +106,87 @@ namespace SabreTools.Hashing
_hasher = HashType switch
{
HashType.Adler32 => new Adler32Context(),
#if NET7_0_OR_GREATER
HashType.BLAKE3 => new Blake3HashAlgorithm(),
#endif
HashType.CRC16_CCITT => new CRC16CcittContext(),
HashType.CRC16_IBM => new CRC16IbmContext(),
#if NET462_OR_GREATER || NETCOREAPP
HashType.CRC32 => new Crc32(),
#else
HashType.CRC32 => new Crc32Context(),
#endif
HashType.CRC32_ISO => new Crc32Context(),
HashType.CRC32_Naive => new NaiveCRC(),
HashType.CRC32_Optimized => new OptimizedCRC(),
HashType.CRC32_Parallel => new ParallelCRC(),
#if NET462_OR_GREATER || NETCOREAPP
HashType.CRC64 => new Crc64(),
#else
HashType.CRC64 => new Crc64Context(CRC64_ECMA_POLY_NORMAL, 0xFFFFFFFFFFFFFFFF),
#endif
HashType.CRC64_Reversed => new Crc64Context(),
HashType.CRC16 => new CrcRunner(StandardDefinitions.CRC16_ARC),
HashType.CRC16_ARC => new CrcRunner(StandardDefinitions.CRC16_ARC),
HashType.CRC16_CDMA2000 => new CrcRunner(StandardDefinitions.CRC16_CDMA2000),
HashType.CRC16_CMS => new CrcRunner(StandardDefinitions.CRC16_CMS),
HashType.CRC16_DDS110 => new CrcRunner(StandardDefinitions.CRC16_DDS110),
HashType.CRC16_DECTR => new CrcRunner(StandardDefinitions.CRC16_DECTR),
HashType.CRC16_DECTX => new CrcRunner(StandardDefinitions.CRC16_DECTX),
HashType.CRC16_DNP => new CrcRunner(StandardDefinitions.CRC16_DNP),
HashType.CRC16_EN13757 => new CrcRunner(StandardDefinitions.CRC16_EN13757),
HashType.CRC16_GENIBUS => new CrcRunner(StandardDefinitions.CRC16_GENIBUS),
HashType.CRC16_GSM => new CrcRunner(StandardDefinitions.CRC16_GSM),
HashType.CRC16_IBM3740 => new CrcRunner(StandardDefinitions.CRC16_IBM3740),
HashType.CRC16_IBMSDLC => new CrcRunner(StandardDefinitions.CRC16_IBMSDLC),
//HashType.CRC16_ISOIEC144433A => new CrcRunner(StandardDefinitions.CRC16_ISOIEC144433A),
HashType.CRC16_KERMIT => new CrcRunner(StandardDefinitions.CRC16_KERMIT),
HashType.CRC16_LJ1200 => new CrcRunner(StandardDefinitions.CRC16_LJ1200),
HashType.CRC16_M17 => new CrcRunner(StandardDefinitions.CRC16_M17),
HashType.CRC16_MAXIMDOW => new CrcRunner(StandardDefinitions.CRC16_MAXIMDOW),
HashType.CRC16_MCRF4XX => new CrcRunner(StandardDefinitions.CRC16_MCRF4XX),
HashType.CRC16_MODBUS => new CrcRunner(StandardDefinitions.CRC16_MODBUS),
HashType.CRC16_NRSC5 => new CrcRunner(StandardDefinitions.CRC16_NRSC5),
HashType.CRC16_OPENSAFETYA => new CrcRunner(StandardDefinitions.CRC16_OPENSAFETYA),
HashType.CRC16_OPENSAFETYB => new CrcRunner(StandardDefinitions.CRC16_OPENSAFETYB),
HashType.CRC16_PROFIBUS => new CrcRunner(StandardDefinitions.CRC16_PROFIBUS),
//HashType.CRC16_RIELLO => new CrcRunner(StandardDefinitions.CRC16_RIELLO),
HashType.CRC16_SPIFUJITSU => new CrcRunner(StandardDefinitions.CRC16_SPIFUJITSU),
HashType.CRC16_T10DIF => new CrcRunner(StandardDefinitions.CRC16_T10DIF),
HashType.CRC16_TELEDISK => new CrcRunner(StandardDefinitions.CRC16_TELEDISK),
//HashType.CRC16_TMS37157 => new CrcRunner(StandardDefinitions.CRC16_TMS37157),
HashType.CRC16_UMTS => new CrcRunner(StandardDefinitions.CRC16_UMTS),
HashType.CRC16_USB => new CrcRunner(StandardDefinitions.CRC16_USB),
HashType.CRC16_XMODEM => new CrcRunner(StandardDefinitions.CRC16_XMODEM),
//HashType.CRC24_BLE => new CrcRunner(StandardDefinitions.CRC24_BLE),
HashType.CRC24_FLEXRAYA => new CrcRunner(StandardDefinitions.CRC24_FLEXRAYA),
HashType.CRC24_FLEXRAYB => new CrcRunner(StandardDefinitions.CRC24_FLEXRAYB),
HashType.CRC24_INTERLAKEN => new CrcRunner(StandardDefinitions.CRC24_INTERLAKEN),
HashType.CRC24_LTEA => new CrcRunner(StandardDefinitions.CRC24_LTEA),
HashType.CRC24_LTEB => new CrcRunner(StandardDefinitions.CRC24_LTEB),
HashType.CRC24_OPENPGP => new CrcRunner(StandardDefinitions.CRC24_OPENPGP),
HashType.CRC24_OS9 => new CrcRunner(StandardDefinitions.CRC24_OS9),
HashType.CRC32 => new CrcRunner(StandardDefinitions.CRC32_ISOHDLC),
HashType.CRC32_AIXM => new CrcRunner(StandardDefinitions.CRC32_AIXM),
HashType.CRC32_AUTOSAR => new CrcRunner(StandardDefinitions.CRC32_AUTOSAR),
HashType.CRC32_BASE91D => new CrcRunner(StandardDefinitions.CRC32_BASE91D),
HashType.CRC32_BZIP2 => new CrcRunner(StandardDefinitions.CRC32_BZIP2),
HashType.CRC32_CDROMEDC => new CrcRunner(StandardDefinitions.CRC32_CDROMEDC),
HashType.CRC32_CKSUM => new CrcRunner(StandardDefinitions.CRC32_CKSUM),
HashType.CRC32_ISCSI => new CrcRunner(StandardDefinitions.CRC32_ISCSI),
HashType.CRC32_ISOHDLC => new CrcRunner(StandardDefinitions.CRC32_ISOHDLC),
HashType.CRC32_JAMCRC => new CrcRunner(StandardDefinitions.CRC32_JAMCRC),
HashType.CRC32_MEF => new CrcRunner(StandardDefinitions.CRC32_MEF),
HashType.CRC32_MPEG2 => new CrcRunner(StandardDefinitions.CRC32_MPEG2),
HashType.CRC32_XFER => new CrcRunner(StandardDefinitions.CRC32_XFER),
HashType.CRC40_GSM => new CrcRunner(StandardDefinitions.CRC40_GSM),
HashType.CRC64 => new CrcRunner(StandardDefinitions.CRC64_ECMA182),
HashType.CRC64_ECMA182 => new CrcRunner(StandardDefinitions.CRC64_ECMA182),
HashType.CRC64_GOISO => new CrcRunner(StandardDefinitions.CRC64_GOISO),
HashType.CRC64_MS => new CrcRunner(StandardDefinitions.CRC64_MS),
HashType.CRC64_NVME => new CrcRunner(StandardDefinitions.CRC64_NVME),
HashType.CRC64_REDIS => new CrcRunner(StandardDefinitions.CRC64_REDIS),
HashType.CRC64_WE => new CrcRunner(StandardDefinitions.CRC64_WE),
HashType.CRC64_XZ => new CrcRunner(StandardDefinitions.CRC64_XZ),
HashType.Fletcher16 => new Fletcher16Context(),
HashType.Fletcher32 => new Fletcher32Context(),
HashType.MD5 => MD5.Create(),
#if NETFRAMEWORK
HashType.RIPEMD160 => RIPEMD160.Create(),
#endif
HashType.SHA1 => SHA1.Create(),
HashType.SHA256 => SHA256.Create(),
HashType.SHA384 => SHA384.Create(),
@@ -173,17 +227,18 @@ namespace SabreTools.Hashing
{
switch (_hasher)
{
case CrcRunner cr:
cr.TransformBlock(buffer, offset, size);
break;
case HashAlgorithm ha:
ha.TransformBlock(buffer, offset, size, null, 0);
break;
case IChecksum ic:
byte[] icBuffer = GetArraySegment(buffer, offset, size);
ic.Update(icBuffer);
break;
case NaiveCRC nc:
nc.Update(buffer, offset, size);
byte[] icBlock = new byte[size];
Array.Copy(buffer, offset, icBlock, 0, size);
ic.Update(icBlock);
break;
#if NET462_OR_GREATER || NETCOREAPP
@@ -193,14 +248,6 @@ namespace SabreTools.Hashing
break;
#endif
case OptimizedCRC oc:
oc.Update(buffer, offset, size);
break;
case ParallelCRC pc:
pc.Update(buffer, offset, size);
break;
#if NET8_0_OR_GREATER
case Shake128 s128:
var s128BufferSpan = new ReadOnlySpan<byte>(buffer, offset, size);
@@ -227,18 +274,6 @@ namespace SabreTools.Hashing
case HashAlgorithm ha:
ha.TransformFinalBlock(emptyBuffer, 0, 0);
break;
case NaiveCRC nc:
nc.Update([], 0, 0);
break;
case OptimizedCRC oc:
oc.Update([], 0, 0);
break;
case ParallelCRC pc:
pc.Update([], 0, 0);
break;
}
}
@@ -269,21 +304,6 @@ namespace SabreTools.Hashing
}
}
/// <summary>
/// Get a segment from the array based on an offset and size
/// </summary>
private static byte[] GetArraySegment(byte[] buffer, int offset, int size)
{
#if NET452_OR_GREATER || NETCOREAPP
var icBufferSpan = new ReadOnlySpan<byte>(buffer, offset, size);
byte[] trimmedBuffer = icBufferSpan.ToArray();
#else
byte[] trimmedBuffer = new byte[size];
Array.Copy(buffer, offset, trimmedBuffer, 0, size);
#endif
return trimmedBuffer;
}
#endregion
}
}

View File

@@ -1,54 +1,56 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.2.0</Version>
<WarningsNotAsErrors>NU5104</WarningsNotAsErrors>
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.2.3</Version>
<WarningsNotAsErrors>NU5104</WarningsNotAsErrors>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
<Copyright>Copyright (c)2016-2024 Matt Nadareski</Copyright>
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SabreTools/SabreTools.Hashing</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>hash hashing checksum checksumming crc md5 sha1</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
<Copyright>Copyright (c)2016-2024 Matt Nadareski</Copyright>
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SabreTools/SabreTools.Hashing</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>hash hashing checksum checksumming crc md5 sha1</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<ItemGroup>
<None Include="../README.md" Pack="true" PackagePath="" />
</ItemGroup>
<!-- Support All Frameworks -->
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>
<!-- Support for old .NET versions -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))">
<PackageReference Include="Net30.LinqBridge" Version="1.3.0" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
<PackageReference Include="MinAsyncBridge" Version="0.12.4" />
<PackageReference Include="MinTasksExtensionsBridge" Version="0.3.4" />
<PackageReference Include="MinThreadingBridge" Version="0.11.4" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net45`)) OR $(TargetFramework.StartsWith(`net46`)) OR $(TargetFramework.StartsWith(`net47`)) OR $(TargetFramework.StartsWith(`net48`))">
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net45`))">
<PackageReference Include="System.IO.Hashing" Version="8.0.0" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
<PackageReference Include="Blake3" Version="1.1.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Aaru.Checksums.Native" Version="6.0.0-alpha9"/>
</ItemGroup>
<ItemGroup>
<None Include="../README.md" Pack="true" PackagePath="" />
</ItemGroup>
</Project>
<!-- Support for old .NET versions -->
<ItemGroup Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net45`))">
<PackageReference Include="System.IO.Hashing" Version="8.0.0" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
<PackageReference Include="Blake3" Version="1.1.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Aaru.Checksums.Native" Version="6.0.0-alpha9" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,524 @@
namespace SabreTools.Hashing.Tiger
{
/// <summary>
/// Tiger S boxes
/// </summary>
public static class SBoxes
{
public static readonly ulong[] Table =
[
0x02AAB17CF7E90C5E /* 0 */, 0xAC424B03E243A8EC /* 1 */,
0x72CD5BE30DD5FCD3 /* 2 */, 0x6D019B93F6F97F3A /* 3 */,
0xCD9978FFD21F9193 /* 4 */, 0x7573A1C9708029E2 /* 5 */,
0xB164326B922A83C3 /* 6 */, 0x46883EEE04915870 /* 7 */,
0xEAACE3057103ECE6 /* 8 */, 0xC54169B808A3535C /* 9 */,
0x4CE754918DDEC47C /* 10 */, 0x0AA2F4DFDC0DF40C /* 11 */,
0x10B76F18A74DBEFA /* 12 */, 0xC6CCB6235AD1AB6A /* 13 */,
0x13726121572FE2FF /* 14 */, 0x1A488C6F199D921E /* 15 */,
0x4BC9F9F4DA0007CA /* 16 */, 0x26F5E6F6E85241C7 /* 17 */,
0x859079DBEA5947B6 /* 18 */, 0x4F1885C5C99E8C92 /* 19 */,
0xD78E761EA96F864B /* 20 */, 0x8E36428C52B5C17D /* 21 */,
0x69CF6827373063C1 /* 22 */, 0xB607C93D9BB4C56E /* 23 */,
0x7D820E760E76B5EA /* 24 */, 0x645C9CC6F07FDC42 /* 25 */,
0xBF38A078243342E0 /* 26 */, 0x5F6B343C9D2E7D04 /* 27 */,
0xF2C28AEB600B0EC6 /* 28 */, 0x6C0ED85F7254BCAC /* 29 */,
0x71592281A4DB4FE5 /* 30 */, 0x1967FA69CE0FED9F /* 31 */,
0xFD5293F8B96545DB /* 32 */, 0xC879E9D7F2A7600B /* 33 */,
0x860248920193194E /* 34 */, 0xA4F9533B2D9CC0B3 /* 35 */,
0x9053836C15957613 /* 36 */, 0xDB6DCF8AFC357BF1 /* 37 */,
0x18BEEA7A7A370F57 /* 38 */, 0x037117CA50B99066 /* 39 */,
0x6AB30A9774424A35 /* 40 */, 0xF4E92F02E325249B /* 41 */,
0x7739DB07061CCAE1 /* 42 */, 0xD8F3B49CECA42A05 /* 43 */,
0xBD56BE3F51382F73 /* 44 */, 0x45FAED5843B0BB28 /* 45 */,
0x1C813D5C11BF1F83 /* 46 */, 0x8AF0E4B6D75FA169 /* 47 */,
0x33EE18A487AD9999 /* 48 */, 0x3C26E8EAB1C94410 /* 49 */,
0xB510102BC0A822F9 /* 50 */, 0x141EEF310CE6123B /* 51 */,
0xFC65B90059DDB154 /* 52 */, 0xE0158640C5E0E607 /* 53 */,
0x884E079826C3A3CF /* 54 */, 0x930D0D9523C535FD /* 55 */,
0x35638D754E9A2B00 /* 56 */, 0x4085FCCF40469DD5 /* 57 */,
0xC4B17AD28BE23A4C /* 58 */, 0xCAB2F0FC6A3E6A2E /* 59 */,
0x2860971A6B943FCD /* 60 */, 0x3DDE6EE212E30446 /* 61 */,
0x6222F32AE01765AE /* 62 */, 0x5D550BB5478308FE /* 63 */,
0xA9EFA98DA0EDA22A /* 64 */, 0xC351A71686C40DA7 /* 65 */,
0x1105586D9C867C84 /* 66 */, 0xDCFFEE85FDA22853 /* 67 */,
0xCCFBD0262C5EEF76 /* 68 */, 0xBAF294CB8990D201 /* 69 */,
0xE69464F52AFAD975 /* 70 */, 0x94B013AFDF133E14 /* 71 */,
0x06A7D1A32823C958 /* 72 */, 0x6F95FE5130F61119 /* 73 */,
0xD92AB34E462C06C0 /* 74 */, 0xED7BDE33887C71D2 /* 75 */,
0x79746D6E6518393E /* 76 */, 0x5BA419385D713329 /* 77 */,
0x7C1BA6B948A97564 /* 78 */, 0x31987C197BFDAC67 /* 79 */,
0xDE6C23C44B053D02 /* 80 */, 0x581C49FED002D64D /* 81 */,
0xDD474D6338261571 /* 82 */, 0xAA4546C3E473D062 /* 83 */,
0x928FCE349455F860 /* 84 */, 0x48161BBACAAB94D9 /* 85 */,
0x63912430770E6F68 /* 86 */, 0x6EC8A5E602C6641C /* 87 */,
0x87282515337DDD2B /* 88 */, 0x2CDA6B42034B701B /* 89 */,
0xB03D37C181CB096D /* 90 */, 0xE108438266C71C6F /* 91 */,
0x2B3180C7EB51B255 /* 92 */, 0xDF92B82F96C08BBC /* 93 */,
0x5C68C8C0A632F3BA /* 94 */, 0x5504CC861C3D0556 /* 95 */,
0xABBFA4E55FB26B8F /* 96 */, 0x41848B0AB3BACEB4 /* 97 */,
0xB334A273AA445D32 /* 98 */, 0xBCA696F0A85AD881 /* 99 */,
0x24F6EC65B528D56C /* 100 */, 0x0CE1512E90F4524A /* 101 */,
0x4E9DD79D5506D35A /* 102 */, 0x258905FAC6CE9779 /* 103 */,
0x2019295B3E109B33 /* 104 */, 0xF8A9478B73A054CC /* 105 */,
0x2924F2F934417EB0 /* 106 */, 0x3993357D536D1BC4 /* 107 */,
0x38A81AC21DB6FF8B /* 108 */, 0x47C4FBF17D6016BF /* 109 */,
0x1E0FAADD7667E3F5 /* 110 */, 0x7ABCFF62938BEB96 /* 111 */,
0xA78DAD948FC179C9 /* 112 */, 0x8F1F98B72911E50D /* 113 */,
0x61E48EAE27121A91 /* 114 */, 0x4D62F7AD31859808 /* 115 */,
0xECEBA345EF5CEAEB /* 116 */, 0xF5CEB25EBC9684CE /* 117 */,
0xF633E20CB7F76221 /* 118 */, 0xA32CDF06AB8293E4 /* 119 */,
0x985A202CA5EE2CA4 /* 120 */, 0xCF0B8447CC8A8FB1 /* 121 */,
0x9F765244979859A3 /* 122 */, 0xA8D516B1A1240017 /* 123 */,
0x0BD7BA3EBB5DC726 /* 124 */, 0xE54BCA55B86ADB39 /* 125 */,
0x1D7A3AFD6C478063 /* 126 */, 0x519EC608E7669EDD /* 127 */,
0x0E5715A2D149AA23 /* 128 */, 0x177D4571848FF194 /* 129 */,
0xEEB55F3241014C22 /* 130 */, 0x0F5E5CA13A6E2EC2 /* 131 */,
0x8029927B75F5C361 /* 132 */, 0xAD139FABC3D6E436 /* 133 */,
0x0D5DF1A94CCF402F /* 134 */, 0x3E8BD948BEA5DFC8 /* 135 */,
0xA5A0D357BD3FF77E /* 136 */, 0xA2D12E251F74F645 /* 137 */,
0x66FD9E525E81A082 /* 138 */, 0x2E0C90CE7F687A49 /* 139 */,
0xC2E8BCBEBA973BC5 /* 140 */, 0x000001BCE509745F /* 141 */,
0x423777BBE6DAB3D6 /* 142 */, 0xD1661C7EAEF06EB5 /* 143 */,
0xA1781F354DAACFD8 /* 144 */, 0x2D11284A2B16AFFC /* 145 */,
0xF1FC4F67FA891D1F /* 146 */, 0x73ECC25DCB920ADA /* 147 */,
0xAE610C22C2A12651 /* 148 */, 0x96E0A810D356B78A /* 149 */,
0x5A9A381F2FE7870F /* 150 */, 0xD5AD62EDE94E5530 /* 151 */,
0xD225E5E8368D1427 /* 152 */, 0x65977B70C7AF4631 /* 153 */,
0x99F889B2DE39D74F /* 154 */, 0x233F30BF54E1D143 /* 155 */,
0x9A9675D3D9A63C97 /* 156 */, 0x5470554FF334F9A8 /* 157 */,
0x166ACB744A4F5688 /* 158 */, 0x70C74CAAB2E4AEAD /* 159 */,
0xF0D091646F294D12 /* 160 */, 0x57B82A89684031D1 /* 161 */,
0xEFD95A5A61BE0B6B /* 162 */, 0x2FBD12E969F2F29A /* 163 */,
0x9BD37013FEFF9FE8 /* 164 */, 0x3F9B0404D6085A06 /* 165 */,
0x4940C1F3166CFE15 /* 166 */, 0x09542C4DCDF3DEFB /* 167 */,
0xB4C5218385CD5CE3 /* 168 */, 0xC935B7DC4462A641 /* 169 */,
0x3417F8A68ED3B63F /* 170 */, 0xB80959295B215B40 /* 171 */,
0xF99CDAEF3B8C8572 /* 172 */, 0x018C0614F8FCB95D /* 173 */,
0x1B14ACCD1A3ACDF3 /* 174 */, 0x84D471F200BB732D /* 175 */,
0xC1A3110E95E8DA16 /* 176 */, 0x430A7220BF1A82B8 /* 177 */,
0xB77E090D39DF210E /* 178 */, 0x5EF4BD9F3CD05E9D /* 179 */,
0x9D4FF6DA7E57A444 /* 180 */, 0xDA1D60E183D4A5F8 /* 181 */,
0xB287C38417998E47 /* 182 */, 0xFE3EDC121BB31886 /* 183 */,
0xC7FE3CCC980CCBEF /* 184 */, 0xE46FB590189BFD03 /* 185 */,
0x3732FD469A4C57DC /* 186 */, 0x7EF700A07CF1AD65 /* 187 */,
0x59C64468A31D8859 /* 188 */, 0x762FB0B4D45B61F6 /* 189 */,
0x155BAED099047718 /* 190 */, 0x68755E4C3D50BAA6 /* 191 */,
0xE9214E7F22D8B4DF /* 192 */, 0x2ADDBF532EAC95F4 /* 193 */,
0x32AE3909B4BD0109 /* 194 */, 0x834DF537B08E3450 /* 195 */,
0xFA209DA84220728D /* 196 */, 0x9E691D9B9EFE23F7 /* 197 */,
0x0446D288C4AE8D7F /* 198 */, 0x7B4CC524E169785B /* 199 */,
0x21D87F0135CA1385 /* 200 */, 0xCEBB400F137B8AA5 /* 201 */,
0x272E2B66580796BE /* 202 */, 0x3612264125C2B0DE /* 203 */,
0x057702BDAD1EFBB2 /* 204 */, 0xD4BABB8EACF84BE9 /* 205 */,
0x91583139641BC67B /* 206 */, 0x8BDC2DE08036E024 /* 207 */,
0x603C8156F49F68ED /* 208 */, 0xF7D236F7DBEF5111 /* 209 */,
0x9727C4598AD21E80 /* 210 */, 0xA08A0896670A5FD7 /* 211 */,
0xCB4A8F4309EBA9CB /* 212 */, 0x81AF564B0F7036A1 /* 213 */,
0xC0B99AA778199ABD /* 214 */, 0x959F1EC83FC8E952 /* 215 */,
0x8C505077794A81B9 /* 216 */, 0x3ACAAF8F056338F0 /* 217 */,
0x07B43F50627A6778 /* 218 */, 0x4A44AB49F5ECCC77 /* 219 */,
0x3BC3D6E4B679EE98 /* 220 */, 0x9CC0D4D1CF14108C /* 221 */,
0x4406C00B206BC8A0 /* 222 */, 0x82A18854C8D72D89 /* 223 */,
0x67E366B35C3C432C /* 224 */, 0xB923DD61102B37F2 /* 225 */,
0x56AB2779D884271D /* 226 */, 0xBE83E1B0FF1525AF /* 227 */,
0xFB7C65D4217E49A9 /* 228 */, 0x6BDBE0E76D48E7D4 /* 229 */,
0x08DF828745D9179E /* 230 */, 0x22EA6A9ADD53BD34 /* 231 */,
0xE36E141C5622200A /* 232 */, 0x7F805D1B8CB750EE /* 233 */,
0xAFE5C7A59F58E837 /* 234 */, 0xE27F996A4FB1C23C /* 235 */,
0xD3867DFB0775F0D0 /* 236 */, 0xD0E673DE6E88891A /* 237 */,
0x123AEB9EAFB86C25 /* 238 */, 0x30F1D5D5C145B895 /* 239 */,
0xBB434A2DEE7269E7 /* 240 */, 0x78CB67ECF931FA38 /* 241 */,
0xF33B0372323BBF9C /* 242 */, 0x52D66336FB279C74 /* 243 */,
0x505F33AC0AFB4EAA /* 244 */, 0xE8A5CD99A2CCE187 /* 245 */,
0x534974801E2D30BB /* 246 */, 0x8D2D5711D5876D90 /* 247 */,
0x1F1A412891BC038E /* 248 */, 0xD6E2E71D82E56648 /* 249 */,
0x74036C3A497732B7 /* 250 */, 0x89B67ED96361F5AB /* 251 */,
0xFFED95D8F1EA02A2 /* 252 */, 0xE72B3BD61464D43D /* 253 */,
0xA6300F170BDC4820 /* 254 */, 0xEBC18760ED78A77A /* 255 */,
0xE6A6BE5A05A12138 /* 256 */, 0xB5A122A5B4F87C98 /* 257 */,
0x563C6089140B6990 /* 258 */, 0x4C46CB2E391F5DD5 /* 259 */,
0xD932ADDBC9B79434 /* 260 */, 0x08EA70E42015AFF5 /* 261 */,
0xD765A6673E478CF1 /* 262 */, 0xC4FB757EAB278D99 /* 263 */,
0xDF11C6862D6E0692 /* 264 */, 0xDDEB84F10D7F3B16 /* 265 */,
0x6F2EF604A665EA04 /* 266 */, 0x4A8E0F0FF0E0DFB3 /* 267 */,
0xA5EDEEF83DBCBA51 /* 268 */, 0xFC4F0A2A0EA4371E /* 269 */,
0xE83E1DA85CB38429 /* 270 */, 0xDC8FF882BA1B1CE2 /* 271 */,
0xCD45505E8353E80D /* 272 */, 0x18D19A00D4DB0717 /* 273 */,
0x34A0CFEDA5F38101 /* 274 */, 0x0BE77E518887CAF2 /* 275 */,
0x1E341438B3C45136 /* 276 */, 0xE05797F49089CCF9 /* 277 */,
0xFFD23F9DF2591D14 /* 278 */, 0x543DDA228595C5CD /* 279 */,
0x661F81FD99052A33 /* 280 */, 0x8736E641DB0F7B76 /* 281 */,
0x15227725418E5307 /* 282 */, 0xE25F7F46162EB2FA /* 283 */,
0x48A8B2126C13D9FE /* 284 */, 0xAFDC541792E76EEA /* 285 */,
0x03D912BFC6D1898F /* 286 */, 0x31B1AAFA1B83F51B /* 287 */,
0xF1AC2796E42AB7D9 /* 288 */, 0x40A3A7D7FCD2EBAC /* 289 */,
0x1056136D0AFBBCC5 /* 290 */, 0x7889E1DD9A6D0C85 /* 291 */,
0xD33525782A7974AA /* 292 */, 0xA7E25D09078AC09B /* 293 */,
0xBD4138B3EAC6EDD0 /* 294 */, 0x920ABFBE71EB9E70 /* 295 */,
0xA2A5D0F54FC2625C /* 296 */, 0xC054E36B0B1290A3 /* 297 */,
0xF6DD59FF62FE932B /* 298 */, 0x3537354511A8AC7D /* 299 */,
0xCA845E9172FADCD4 /* 300 */, 0x84F82B60329D20DC /* 301 */,
0x79C62CE1CD672F18 /* 302 */, 0x8B09A2ADD124642C /* 303 */,
0xD0C1E96A19D9E726 /* 304 */, 0x5A786A9B4BA9500C /* 305 */,
0x0E020336634C43F3 /* 306 */, 0xC17B474AEB66D822 /* 307 */,
0x6A731AE3EC9BAAC2 /* 308 */, 0x8226667AE0840258 /* 309 */,
0x67D4567691CAECA5 /* 310 */, 0x1D94155C4875ADB5 /* 311 */,
0x6D00FD985B813FDF /* 312 */, 0x51286EFCB774CD06 /* 313 */,
0x5E8834471FA744AF /* 314 */, 0xF72CA0AEE761AE2E /* 315 */,
0xBE40E4CDAEE8E09A /* 316 */, 0xE9970BBB5118F665 /* 317 */,
0x726E4BEB33DF1964 /* 318 */, 0x703B000729199762 /* 319 */,
0x4631D816F5EF30A7 /* 320 */, 0xB880B5B51504A6BE /* 321 */,
0x641793C37ED84B6C /* 322 */, 0x7B21ED77F6E97D96 /* 323 */,
0x776306312EF96B73 /* 324 */, 0xAE528948E86FF3F4 /* 325 */,
0x53DBD7F286A3F8F8 /* 326 */, 0x16CADCE74CFC1063 /* 327 */,
0x005C19BDFA52C6DD /* 328 */, 0x68868F5D64D46AD3 /* 329 */,
0x3A9D512CCF1E186A /* 330 */, 0x367E62C2385660AE /* 331 */,
0xE359E7EA77DCB1D7 /* 332 */, 0x526C0773749ABE6E /* 333 */,
0x735AE5F9D09F734B /* 334 */, 0x493FC7CC8A558BA8 /* 335 */,
0xB0B9C1533041AB45 /* 336 */, 0x321958BA470A59BD /* 337 */,
0x852DB00B5F46C393 /* 338 */, 0x91209B2BD336B0E5 /* 339 */,
0x6E604F7D659EF19F /* 340 */, 0xB99A8AE2782CCB24 /* 341 */,
0xCCF52AB6C814C4C7 /* 342 */, 0x4727D9AFBE11727B /* 343 */,
0x7E950D0C0121B34D /* 344 */, 0x756F435670AD471F /* 345 */,
0xF5ADD442615A6849 /* 346 */, 0x4E87E09980B9957A /* 347 */,
0x2ACFA1DF50AEE355 /* 348 */, 0xD898263AFD2FD556 /* 349 */,
0xC8F4924DD80C8FD6 /* 350 */, 0xCF99CA3D754A173A /* 351 */,
0xFE477BACAF91BF3C /* 352 */, 0xED5371F6D690C12D /* 353 */,
0x831A5C285E687094 /* 354 */, 0xC5D3C90A3708A0A4 /* 355 */,
0x0F7F903717D06580 /* 356 */, 0x19F9BB13B8FDF27F /* 357 */,
0xB1BD6F1B4D502843 /* 358 */, 0x1C761BA38FFF4012 /* 359 */,
0x0D1530C4E2E21F3B /* 360 */, 0x8943CE69A7372C8A /* 361 */,
0xE5184E11FEB5CE66 /* 362 */, 0x618BDB80BD736621 /* 363 */,
0x7D29BAD68B574D0B /* 364 */, 0x81BB613E25E6FE5B /* 365 */,
0x071C9C10BC07913F /* 366 */, 0xC7BEEB7909AC2D97 /* 367 */,
0xC3E58D353BC5D757 /* 368 */, 0xEB017892F38F61E8 /* 369 */,
0xD4EFFB9C9B1CC21A /* 370 */, 0x99727D26F494F7AB /* 371 */,
0xA3E063A2956B3E03 /* 372 */, 0x9D4A8B9A4AA09C30 /* 373 */,
0x3F6AB7D500090FB4 /* 374 */, 0x9CC0F2A057268AC0 /* 375 */,
0x3DEE9D2DEDBF42D1 /* 376 */, 0x330F49C87960A972 /* 377 */,
0xC6B2720287421B41 /* 378 */, 0x0AC59EC07C00369C /* 379 */,
0xEF4EAC49CB353425 /* 380 */, 0xF450244EEF0129D8 /* 381 */,
0x8ACC46E5CAF4DEB6 /* 382 */, 0x2FFEAB63989263F7 /* 383 */,
0x8F7CB9FE5D7A4578 /* 384 */, 0x5BD8F7644E634635 /* 385 */,
0x427A7315BF2DC900 /* 386 */, 0x17D0C4AA2125261C /* 387 */,
0x3992486C93518E50 /* 388 */, 0xB4CBFEE0A2D7D4C3 /* 389 */,
0x7C75D6202C5DDD8D /* 390 */, 0xDBC295D8E35B6C61 /* 391 */,
0x60B369D302032B19 /* 392 */, 0xCE42685FDCE44132 /* 393 */,
0x06F3DDB9DDF65610 /* 394 */, 0x8EA4D21DB5E148F0 /* 395 */,
0x20B0FCE62FCD496F /* 396 */, 0x2C1B912358B0EE31 /* 397 */,
0xB28317B818F5A308 /* 398 */, 0xA89C1E189CA6D2CF /* 399 */,
0x0C6B18576AAADBC8 /* 400 */, 0xB65DEAA91299FAE3 /* 401 */,
0xFB2B794B7F1027E7 /* 402 */, 0x04E4317F443B5BEB /* 403 */,
0x4B852D325939D0A6 /* 404 */, 0xD5AE6BEEFB207FFC /* 405 */,
0x309682B281C7D374 /* 406 */, 0xBAE309A194C3B475 /* 407 */,
0x8CC3F97B13B49F05 /* 408 */, 0x98A9422FF8293967 /* 409 */,
0x244B16B01076FF7C /* 410 */, 0xF8BF571C663D67EE /* 411 */,
0x1F0D6758EEE30DA1 /* 412 */, 0xC9B611D97ADEB9B7 /* 413 */,
0xB7AFD5887B6C57A2 /* 414 */, 0x6290AE846B984FE1 /* 415 */,
0x94DF4CDEACC1A5FD /* 416 */, 0x058A5BD1C5483AFF /* 417 */,
0x63166CC142BA3C37 /* 418 */, 0x8DB8526EB2F76F40 /* 419 */,
0xE10880036F0D6D4E /* 420 */, 0x9E0523C9971D311D /* 421 */,
0x45EC2824CC7CD691 /* 422 */, 0x575B8359E62382C9 /* 423 */,
0xFA9E400DC4889995 /* 424 */, 0xD1823ECB45721568 /* 425 */,
0xDAFD983B8206082F /* 426 */, 0xAA7D29082386A8CB /* 427 */,
0x269FCD4403B87588 /* 428 */, 0x1B91F5F728BDD1E0 /* 429 */,
0xE4669F39040201F6 /* 430 */, 0x7A1D7C218CF04ADE /* 431 */,
0x65623C29D79CE5CE /* 432 */, 0x2368449096C00BB1 /* 433 */,
0xAB9BF1879DA503BA /* 434 */, 0xBC23ECB1A458058E /* 435 */,
0x9A58DF01BB401ECC /* 436 */, 0xA070E868A85F143D /* 437 */,
0x4FF188307DF2239E /* 438 */, 0x14D565B41A641183 /* 439 */,
0xEE13337452701602 /* 440 */, 0x950E3DCF3F285E09 /* 441 */,
0x59930254B9C80953 /* 442 */, 0x3BF299408930DA6D /* 443 */,
0xA955943F53691387 /* 444 */, 0xA15EDECAA9CB8784 /* 445 */,
0x29142127352BE9A0 /* 446 */, 0x76F0371FFF4E7AFB /* 447 */,
0x0239F450274F2228 /* 448 */, 0xBB073AF01D5E868B /* 449 */,
0xBFC80571C10E96C1 /* 450 */, 0xD267088568222E23 /* 451 */,
0x9671A3D48E80B5B0 /* 452 */, 0x55B5D38AE193BB81 /* 453 */,
0x693AE2D0A18B04B8 /* 454 */, 0x5C48B4ECADD5335F /* 455 */,
0xFD743B194916A1CA /* 456 */, 0x2577018134BE98C4 /* 457 */,
0xE77987E83C54A4AD /* 458 */, 0x28E11014DA33E1B9 /* 459 */,
0x270CC59E226AA213 /* 460 */, 0x71495F756D1A5F60 /* 461 */,
0x9BE853FB60AFEF77 /* 462 */, 0xADC786A7F7443DBF /* 463 */,
0x0904456173B29A82 /* 464 */, 0x58BC7A66C232BD5E /* 465 */,
0xF306558C673AC8B2 /* 466 */, 0x41F639C6B6C9772A /* 467 */,
0x216DEFE99FDA35DA /* 468 */, 0x11640CC71C7BE615 /* 469 */,
0x93C43694565C5527 /* 470 */, 0xEA038E6246777839 /* 471 */,
0xF9ABF3CE5A3E2469 /* 472 */, 0x741E768D0FD312D2 /* 473 */,
0x0144B883CED652C6 /* 474 */, 0xC20B5A5BA33F8552 /* 475 */,
0x1AE69633C3435A9D /* 476 */, 0x97A28CA4088CFDEC /* 477 */,
0x8824A43C1E96F420 /* 478 */, 0x37612FA66EEEA746 /* 479 */,
0x6B4CB165F9CF0E5A /* 480 */, 0x43AA1C06A0ABFB4A /* 481 */,
0x7F4DC26FF162796B /* 482 */, 0x6CBACC8E54ED9B0F /* 483 */,
0xA6B7FFEFD2BB253E /* 484 */, 0x2E25BC95B0A29D4F /* 485 */,
0x86D6A58BDEF1388C /* 486 */, 0xDED74AC576B6F054 /* 487 */,
0x8030BDBC2B45805D /* 488 */, 0x3C81AF70E94D9289 /* 489 */,
0x3EFF6DDA9E3100DB /* 490 */, 0xB38DC39FDFCC8847 /* 491 */,
0x123885528D17B87E /* 492 */, 0xF2DA0ED240B1B642 /* 493 */,
0x44CEFADCD54BF9A9 /* 494 */, 0x1312200E433C7EE6 /* 495 */,
0x9FFCC84F3A78C748 /* 496 */, 0xF0CD1F72248576BB /* 497 */,
0xEC6974053638CFE4 /* 498 */, 0x2BA7B67C0CEC4E4C /* 499 */,
0xAC2F4DF3E5CE32ED /* 500 */, 0xCB33D14326EA4C11 /* 501 */,
0xA4E9044CC77E58BC /* 502 */, 0x5F513293D934FCEF /* 503 */,
0x5DC9645506E55444 /* 504 */, 0x50DE418F317DE40A /* 505 */,
0x388CB31A69DDE259 /* 506 */, 0x2DB4A83455820A86 /* 507 */,
0x9010A91E84711AE9 /* 508 */, 0x4DF7F0B7B1498371 /* 509 */,
0xD62A2EABC0977179 /* 510 */, 0x22FAC097AA8D5C0E /* 511 */,
0xF49FCC2FF1DAF39B /* 512 */, 0x487FD5C66FF29281 /* 513 */,
0xE8A30667FCDCA83F /* 514 */, 0x2C9B4BE3D2FCCE63 /* 515 */,
0xDA3FF74B93FBBBC2 /* 516 */, 0x2FA165D2FE70BA66 /* 517 */,
0xA103E279970E93D4 /* 518 */, 0xBECDEC77B0E45E71 /* 519 */,
0xCFB41E723985E497 /* 520 */, 0xB70AAA025EF75017 /* 521 */,
0xD42309F03840B8E0 /* 522 */, 0x8EFC1AD035898579 /* 523 */,
0x96C6920BE2B2ABC5 /* 524 */, 0x66AF4163375A9172 /* 525 */,
0x2174ABDCCA7127FB /* 526 */, 0xB33CCEA64A72FF41 /* 527 */,
0xF04A4933083066A5 /* 528 */, 0x8D970ACDD7289AF5 /* 529 */,
0x8F96E8E031C8C25E /* 530 */, 0xF3FEC02276875D47 /* 531 */,
0xEC7BF310056190DD /* 532 */, 0xF5ADB0AEBB0F1491 /* 533 */,
0x9B50F8850FD58892 /* 534 */, 0x4975488358B74DE8 /* 535 */,
0xA3354FF691531C61 /* 536 */, 0x0702BBE481D2C6EE /* 537 */,
0x89FB24057DEDED98 /* 538 */, 0xAC3075138596E902 /* 539 */,
0x1D2D3580172772ED /* 540 */, 0xEB738FC28E6BC30D /* 541 */,
0x5854EF8F63044326 /* 542 */, 0x9E5C52325ADD3BBE /* 543 */,
0x90AA53CF325C4623 /* 544 */, 0xC1D24D51349DD067 /* 545 */,
0x2051CFEEA69EA624 /* 546 */, 0x13220F0A862E7E4F /* 547 */,
0xCE39399404E04864 /* 548 */, 0xD9C42CA47086FCB7 /* 549 */,
0x685AD2238A03E7CC /* 550 */, 0x066484B2AB2FF1DB /* 551 */,
0xFE9D5D70EFBF79EC /* 552 */, 0x5B13B9DD9C481854 /* 553 */,
0x15F0D475ED1509AD /* 554 */, 0x0BEBCD060EC79851 /* 555 */,
0xD58C6791183AB7F8 /* 556 */, 0xD1187C5052F3EEE4 /* 557 */,
0xC95D1192E54E82FF /* 558 */, 0x86EEA14CB9AC6CA2 /* 559 */,
0x3485BEB153677D5D /* 560 */, 0xDD191D781F8C492A /* 561 */,
0xF60866BAA784EBF9 /* 562 */, 0x518F643BA2D08C74 /* 563 */,
0x8852E956E1087C22 /* 564 */, 0xA768CB8DC410AE8D /* 565 */,
0x38047726BFEC8E1A /* 566 */, 0xA67738B4CD3B45AA /* 567 */,
0xAD16691CEC0DDE19 /* 568 */, 0xC6D4319380462E07 /* 569 */,
0xC5A5876D0BA61938 /* 570 */, 0x16B9FA1FA58FD840 /* 571 */,
0x188AB1173CA74F18 /* 572 */, 0xABDA2F98C99C021F /* 573 */,
0x3E0580AB134AE816 /* 574 */, 0x5F3B05B773645ABB /* 575 */,
0x2501A2BE5575F2F6 /* 576 */, 0x1B2F74004E7E8BA9 /* 577 */,
0x1CD7580371E8D953 /* 578 */, 0x7F6ED89562764E30 /* 579 */,
0xB15926FF596F003D /* 580 */, 0x9F65293DA8C5D6B9 /* 581 */,
0x6ECEF04DD690F84C /* 582 */, 0x4782275FFF33AF88 /* 583 */,
0xE41433083F820801 /* 584 */, 0xFD0DFE409A1AF9B5 /* 585 */,
0x4325A3342CDB396B /* 586 */, 0x8AE77E62B301B252 /* 587 */,
0xC36F9E9F6655615A /* 588 */, 0x85455A2D92D32C09 /* 589 */,
0xF2C7DEA949477485 /* 590 */, 0x63CFB4C133A39EBA /* 591 */,
0x83B040CC6EBC5462 /* 592 */, 0x3B9454C8FDB326B0 /* 593 */,
0x56F56A9E87FFD78C /* 594 */, 0x2DC2940D99F42BC6 /* 595 */,
0x98F7DF096B096E2D /* 596 */, 0x19A6E01E3AD852BF /* 597 */,
0x42A99CCBDBD4B40B /* 598 */, 0xA59998AF45E9C559 /* 599 */,
0x366295E807D93186 /* 600 */, 0x6B48181BFAA1F773 /* 601 */,
0x1FEC57E2157A0A1D /* 602 */, 0x4667446AF6201AD5 /* 603 */,
0xE615EBCACFB0F075 /* 604 */, 0xB8F31F4F68290778 /* 605 */,
0x22713ED6CE22D11E /* 606 */, 0x3057C1A72EC3C93B /* 607 */,
0xCB46ACC37C3F1F2F /* 608 */, 0xDBB893FD02AAF50E /* 609 */,
0x331FD92E600B9FCF /* 610 */, 0xA498F96148EA3AD6 /* 611 */,
0xA8D8426E8B6A83EA /* 612 */, 0xA089B274B7735CDC /* 613 */,
0x87F6B3731E524A11 /* 614 */, 0x118808E5CBC96749 /* 615 */,
0x9906E4C7B19BD394 /* 616 */, 0xAFED7F7E9B24A20C /* 617 */,
0x6509EADEEB3644A7 /* 618 */, 0x6C1EF1D3E8EF0EDE /* 619 */,
0xB9C97D43E9798FB4 /* 620 */, 0xA2F2D784740C28A3 /* 621 */,
0x7B8496476197566F /* 622 */, 0x7A5BE3E6B65F069D /* 623 */,
0xF96330ED78BE6F10 /* 624 */, 0xEEE60DE77A076A15 /* 625 */,
0x2B4BEE4AA08B9BD0 /* 626 */, 0x6A56A63EC7B8894E /* 627 */,
0x02121359BA34FEF4 /* 628 */, 0x4CBF99F8283703FC /* 629 */,
0x398071350CAF30C8 /* 630 */, 0xD0A77A89F017687A /* 631 */,
0xF1C1A9EB9E423569 /* 632 */, 0x8C7976282DEE8199 /* 633 */,
0x5D1737A5DD1F7ABD /* 634 */, 0x4F53433C09A9FA80 /* 635 */,
0xFA8B0C53DF7CA1D9 /* 636 */, 0x3FD9DCBC886CCB77 /* 637 */,
0xC040917CA91B4720 /* 638 */, 0x7DD00142F9D1DCDF /* 639 */,
0x8476FC1D4F387B58 /* 640 */, 0x23F8E7C5F3316503 /* 641 */,
0x032A2244E7E37339 /* 642 */, 0x5C87A5D750F5A74B /* 643 */,
0x082B4CC43698992E /* 644 */, 0xDF917BECB858F63C /* 645 */,
0x3270B8FC5BF86DDA /* 646 */, 0x10AE72BB29B5DD76 /* 647 */,
0x576AC94E7700362B /* 648 */, 0x1AD112DAC61EFB8F /* 649 */,
0x691BC30EC5FAA427 /* 650 */, 0xFF246311CC327143 /* 651 */,
0x3142368E30E53206 /* 652 */, 0x71380E31E02CA396 /* 653 */,
0x958D5C960AAD76F1 /* 654 */, 0xF8D6F430C16DA536 /* 655 */,
0xC8FFD13F1BE7E1D2 /* 656 */, 0x7578AE66004DDBE1 /* 657 */,
0x05833F01067BE646 /* 658 */, 0xBB34B5AD3BFE586D /* 659 */,
0x095F34C9A12B97F0 /* 660 */, 0x247AB64525D60CA8 /* 661 */,
0xDCDBC6F3017477D1 /* 662 */, 0x4A2E14D4DECAD24D /* 663 */,
0xBDB5E6D9BE0A1EEB /* 664 */, 0x2A7E70F7794301AB /* 665 */,
0xDEF42D8A270540FD /* 666 */, 0x01078EC0A34C22C1 /* 667 */,
0xE5DE511AF4C16387 /* 668 */, 0x7EBB3A52BD9A330A /* 669 */,
0x77697857AA7D6435 /* 670 */, 0x004E831603AE4C32 /* 671 */,
0xE7A21020AD78E312 /* 672 */, 0x9D41A70C6AB420F2 /* 673 */,
0x28E06C18EA1141E6 /* 674 */, 0xD2B28CBD984F6B28 /* 675 */,
0x26B75F6C446E9D83 /* 676 */, 0xBA47568C4D418D7F /* 677 */,
0xD80BADBFE6183D8E /* 678 */, 0x0E206D7F5F166044 /* 679 */,
0xE258A43911CBCA3E /* 680 */, 0x723A1746B21DC0BC /* 681 */,
0xC7CAA854F5D7CDD3 /* 682 */, 0x7CAC32883D261D9C /* 683 */,
0x7690C26423BA942C /* 684 */, 0x17E55524478042B8 /* 685 */,
0xE0BE477656A2389F /* 686 */, 0x4D289B5E67AB2DA0 /* 687 */,
0x44862B9C8FBBFD31 /* 688 */, 0xB47CC8049D141365 /* 689 */,
0x822C1B362B91C793 /* 690 */, 0x4EB14655FB13DFD8 /* 691 */,
0x1ECBBA0714E2A97B /* 692 */, 0x6143459D5CDE5F14 /* 693 */,
0x53A8FBF1D5F0AC89 /* 694 */, 0x97EA04D81C5E5B00 /* 695 */,
0x622181A8D4FDB3F3 /* 696 */, 0xE9BCD341572A1208 /* 697 */,
0x1411258643CCE58A /* 698 */, 0x9144C5FEA4C6E0A4 /* 699 */,
0x0D33D06565CF620F /* 700 */, 0x54A48D489F219CA1 /* 701 */,
0xC43E5EAC6D63C821 /* 702 */, 0xA9728B3A72770DAF /* 703 */,
0xD7934E7B20DF87EF /* 704 */, 0xE35503B61A3E86E5 /* 705 */,
0xCAE321FBC819D504 /* 706 */, 0x129A50B3AC60BFA6 /* 707 */,
0xCD5E68EA7E9FB6C3 /* 708 */, 0xB01C90199483B1C7 /* 709 */,
0x3DE93CD5C295376C /* 710 */, 0xAED52EDF2AB9AD13 /* 711 */,
0x2E60F512C0A07884 /* 712 */, 0xBC3D86A3E36210C9 /* 713 */,
0x35269D9B163951CE /* 714 */, 0x0C7D6E2AD0CDB5FA /* 715 */,
0x59E86297D87F5733 /* 716 */, 0x298EF221898DB0E7 /* 717 */,
0x55000029D1A5AA7E /* 718 */, 0x8BC08AE1B5061B45 /* 719 */,
0xC2C31C2B6C92703A /* 720 */, 0x94CC596BAF25EF42 /* 721 */,
0x0A1D73DB22540456 /* 722 */, 0x04B6A0F9D9C4179A /* 723 */,
0xEFFDAFA2AE3D3C60 /* 724 */, 0xF7C8075BB49496C4 /* 725 */,
0x9CC5C7141D1CD4E3 /* 726 */, 0x78BD1638218E5534 /* 727 */,
0xB2F11568F850246A /* 728 */, 0xEDFABCFA9502BC29 /* 729 */,
0x796CE5F2DA23051B /* 730 */, 0xAAE128B0DC93537C /* 731 */,
0x3A493DA0EE4B29AE /* 732 */, 0xB5DF6B2C416895D7 /* 733 */,
0xFCABBD25122D7F37 /* 734 */, 0x70810B58105DC4B1 /* 735 */,
0xE10FDD37F7882A90 /* 736 */, 0x524DCAB5518A3F5C /* 737 */,
0x3C9E85878451255B /* 738 */, 0x4029828119BD34E2 /* 739 */,
0x74A05B6F5D3CECCB /* 740 */, 0xB610021542E13ECA /* 741 */,
0x0FF979D12F59E2AC /* 742 */, 0x6037DA27E4F9CC50 /* 743 */,
0x5E92975A0DF1847D /* 744 */, 0xD66DE190D3E623FE /* 745 */,
0x5032D6B87B568048 /* 746 */, 0x9A36B7CE8235216E /* 747 */,
0x80272A7A24F64B4A /* 748 */, 0x93EFED8B8C6916F7 /* 749 */,
0x37DDBFF44CCE1555 /* 750 */, 0x4B95DB5D4B99BD25 /* 751 */,
0x92D3FDA169812FC0 /* 752 */, 0xFB1A4A9A90660BB6 /* 753 */,
0x730C196946A4B9B2 /* 754 */, 0x81E289AA7F49DA68 /* 755 */,
0x64669A0F83B1A05F /* 756 */, 0x27B3FF7D9644F48B /* 757 */,
0xCC6B615C8DB675B3 /* 758 */, 0x674F20B9BCEBBE95 /* 759 */,
0x6F31238275655982 /* 760 */, 0x5AE488713E45CF05 /* 761 */,
0xBF619F9954C21157 /* 762 */, 0xEABAC46040A8EAE9 /* 763 */,
0x454C6FE9F2C0C1CD /* 764 */, 0x419CF6496412691C /* 765 */,
0xD3DC3BEF265B0F70 /* 766 */, 0x6D0E60F5C3578A9E /* 767 */,
0x5B0E608526323C55 /* 768 */, 0x1A46C1A9FA1B59F5 /* 769 */,
0xA9E245A17C4C8FFA /* 770 */, 0x65CA5159DB2955D7 /* 771 */,
0x05DB0A76CE35AFC2 /* 772 */, 0x81EAC77EA9113D45 /* 773 */,
0x528EF88AB6AC0A0D /* 774 */, 0xA09EA253597BE3FF /* 775 */,
0x430DDFB3AC48CD56 /* 776 */, 0xC4B3A67AF45CE46F /* 777 */,
0x4ECECFD8FBE2D05E /* 778 */, 0x3EF56F10B39935F0 /* 779 */,
0x0B22D6829CD619C6 /* 780 */, 0x17FD460A74DF2069 /* 781 */,
0x6CF8CC8E8510ED40 /* 782 */, 0xD6C824BF3A6ECAA7 /* 783 */,
0x61243D581A817049 /* 784 */, 0x048BACB6BBC163A2 /* 785 */,
0xD9A38AC27D44CC32 /* 786 */, 0x7FDDFF5BAAF410AB /* 787 */,
0xAD6D495AA804824B /* 788 */, 0xE1A6A74F2D8C9F94 /* 789 */,
0xD4F7851235DEE8E3 /* 790 */, 0xFD4B7F886540D893 /* 791 */,
0x247C20042AA4BFDA /* 792 */, 0x096EA1C517D1327C /* 793 */,
0xD56966B4361A6685 /* 794 */, 0x277DA5C31221057D /* 795 */,
0x94D59893A43ACFF7 /* 796 */, 0x64F0C51CCDC02281 /* 797 */,
0x3D33BCC4FF6189DB /* 798 */, 0xE005CB184CE66AF1 /* 799 */,
0xFF5CCD1D1DB99BEA /* 800 */, 0xB0B854A7FE42980F /* 801 */,
0x7BD46A6A718D4B9F /* 802 */, 0xD10FA8CC22A5FD8C /* 803 */,
0xD31484952BE4BD31 /* 804 */, 0xC7FA975FCB243847 /* 805 */,
0x4886ED1E5846C407 /* 806 */, 0x28CDDB791EB70B04 /* 807 */,
0xC2B00BE2F573417F /* 808 */, 0x5C9590452180F877 /* 809 */,
0x7A6BDDFFF370EB00 /* 810 */, 0xCE509E38D6D9D6A4 /* 811 */,
0xEBEB0F00647FA702 /* 812 */, 0x1DCC06CF76606F06 /* 813 */,
0xE4D9F28BA286FF0A /* 814 */, 0xD85A305DC918C262 /* 815 */,
0x475B1D8732225F54 /* 816 */, 0x2D4FB51668CCB5FE /* 817 */,
0xA679B9D9D72BBA20 /* 818 */, 0x53841C0D912D43A5 /* 819 */,
0x3B7EAA48BF12A4E8 /* 820 */, 0x781E0E47F22F1DDF /* 821 */,
0xEFF20CE60AB50973 /* 822 */, 0x20D261D19DFFB742 /* 823 */,
0x16A12B03062A2E39 /* 824 */, 0x1960EB2239650495 /* 825 */,
0x251C16FED50EB8B8 /* 826 */, 0x9AC0C330F826016E /* 827 */,
0xED152665953E7671 /* 828 */, 0x02D63194A6369570 /* 829 */,
0x5074F08394B1C987 /* 830 */, 0x70BA598C90B25CE1 /* 831 */,
0x794A15810B9742F6 /* 832 */, 0x0D5925E9FCAF8C6C /* 833 */,
0x3067716CD868744E /* 834 */, 0x910AB077E8D7731B /* 835 */,
0x6A61BBDB5AC42F61 /* 836 */, 0x93513EFBF0851567 /* 837 */,
0xF494724B9E83E9D5 /* 838 */, 0xE887E1985C09648D /* 839 */,
0x34B1D3C675370CFD /* 840 */, 0xDC35E433BC0D255D /* 841 */,
0xD0AAB84234131BE0 /* 842 */, 0x08042A50B48B7EAF /* 843 */,
0x9997C4EE44A3AB35 /* 844 */, 0x829A7B49201799D0 /* 845 */,
0x263B8307B7C54441 /* 846 */, 0x752F95F4FD6A6CA6 /* 847 */,
0x927217402C08C6E5 /* 848 */, 0x2A8AB754A795D9EE /* 849 */,
0xA442F7552F72943D /* 850 */, 0x2C31334E19781208 /* 851 */,
0x4FA98D7CEAEE6291 /* 852 */, 0x55C3862F665DB309 /* 853 */,
0xBD0610175D53B1F3 /* 854 */, 0x46FE6CB840413F27 /* 855 */,
0x3FE03792DF0CFA59 /* 856 */, 0xCFE700372EB85E8F /* 857 */,
0xA7BE29E7ADBCE118 /* 858 */, 0xE544EE5CDE8431DD /* 859 */,
0x8A781B1B41F1873E /* 860 */, 0xA5C94C78A0D2F0E7 /* 861 */,
0x39412E2877B60728 /* 862 */, 0xA1265EF3AFC9A62C /* 863 */,
0xBCC2770C6A2506C5 /* 864 */, 0x3AB66DD5DCE1CE12 /* 865 */,
0xE65499D04A675B37 /* 866 */, 0x7D8F523481BFD216 /* 867 */,
0x0F6F64FCEC15F389 /* 868 */, 0x74EFBE618B5B13C8 /* 869 */,
0xACDC82B714273E1D /* 870 */, 0xDD40BFE003199D17 /* 871 */,
0x37E99257E7E061F8 /* 872 */, 0xFA52626904775AAA /* 873 */,
0x8BBBF63A463D56F9 /* 874 */, 0xF0013F1543A26E64 /* 875 */,
0xA8307E9F879EC898 /* 876 */, 0xCC4C27A4150177CC /* 877 */,
0x1B432F2CCA1D3348 /* 878 */, 0xDE1D1F8F9F6FA013 /* 879 */,
0x606602A047A7DDD6 /* 880 */, 0xD237AB64CC1CB2C7 /* 881 */,
0x9B938E7225FCD1D3 /* 882 */, 0xEC4E03708E0FF476 /* 883 */,
0xFEB2FBDA3D03C12D /* 884 */, 0xAE0BCED2EE43889A /* 885 */,
0x22CB8923EBFB4F43 /* 886 */, 0x69360D013CF7396D /* 887 */,
0x855E3602D2D4E022 /* 888 */, 0x073805BAD01F784C /* 889 */,
0x33E17A133852F546 /* 890 */, 0xDF4874058AC7B638 /* 891 */,
0xBA92B29C678AA14A /* 892 */, 0x0CE89FC76CFAADCD /* 893 */,
0x5F9D4E0908339E34 /* 894 */, 0xF1AFE9291F5923B9 /* 895 */,
0x6E3480F60F4A265F /* 896 */, 0xEEBF3A2AB29B841C /* 897 */,
0xE21938A88F91B4AD /* 898 */, 0x57DFEFF845C6D3C3 /* 899 */,
0x2F006B0BF62CAAF2 /* 900 */, 0x62F479EF6F75EE78 /* 901 */,
0x11A55AD41C8916A9 /* 902 */, 0xF229D29084FED453 /* 903 */,
0x42F1C27B16B000E6 /* 904 */, 0x2B1F76749823C074 /* 905 */,
0x4B76ECA3C2745360 /* 906 */, 0x8C98F463B91691BD /* 907 */,
0x14BCC93CF1ADE66A /* 908 */, 0x8885213E6D458397 /* 909 */,
0x8E177DF0274D4711 /* 910 */, 0xB49B73B5503F2951 /* 911 */,
0x10168168C3F96B6B /* 912 */, 0x0E3D963B63CAB0AE /* 913 */,
0x8DFC4B5655A1DB14 /* 914 */, 0xF789F1356E14DE5C /* 915 */,
0x683E68AF4E51DAC1 /* 916 */, 0xC9A84F9D8D4B0FD9 /* 917 */,
0x3691E03F52A0F9D1 /* 918 */, 0x5ED86E46E1878E80 /* 919 */,
0x3C711A0E99D07150 /* 920 */, 0x5A0865B20C4E9310 /* 921 */,
0x56FBFC1FE4F0682E /* 922 */, 0xEA8D5DE3105EDF9B /* 923 */,
0x71ABFDB12379187A /* 924 */, 0x2EB99DE1BEE77B9C /* 925 */,
0x21ECC0EA33CF4523 /* 926 */, 0x59A4D7521805C7A1 /* 927 */,
0x3896F5EB56AE7C72 /* 928 */, 0xAA638F3DB18F75DC /* 929 */,
0x9F39358DABE9808E /* 930 */, 0xB7DEFA91C00B72AC /* 931 */,
0x6B5541FD62492D92 /* 932 */, 0x6DC6DEE8F92E4D5B /* 933 */,
0x353F57ABC4BEEA7E /* 934 */, 0x735769D6DA5690CE /* 935 */,
0x0A234AA642391484 /* 936 */, 0xF6F9508028F80D9D /* 937 */,
0xB8E319A27AB3F215 /* 938 */, 0x31AD9C1151341A4D /* 939 */,
0x773C22A57BEF5805 /* 940 */, 0x45C7561A07968633 /* 941 */,
0xF913DA9E249DBE36 /* 942 */, 0xDA652D9B78A64C68 /* 943 */,
0x4C27A97F3BC334EF /* 944 */, 0x76621220E66B17F4 /* 945 */,
0x967743899ACD7D0B /* 946 */, 0xF3EE5BCAE0ED6782 /* 947 */,
0x409F753600C879FC /* 948 */, 0x06D09A39B5926DB6 /* 949 */,
0x6F83AEB0317AC588 /* 950 */, 0x01E6CA4A86381F21 /* 951 */,
0x66FF3462D19F3025 /* 952 */, 0x72207C24DDFD3BFB /* 953 */,
0x4AF6B6D3E2ECE2EB /* 954 */, 0x9C994DBEC7EA08DE /* 955 */,
0x49ACE597B09A8BC4 /* 956 */, 0xB38C4766CF0797BA /* 957 */,
0x131B9373C57C2A75 /* 958 */, 0xB1822CCE61931E58 /* 959 */,
0x9D7555B909BA1C0C /* 960 */, 0x127FAFDD937D11D2 /* 961 */,
0x29DA3BADC66D92E4 /* 962 */, 0xA2C1D57154C2ECBC /* 963 */,
0x58C5134D82F6FE24 /* 964 */, 0x1C3AE3515B62274F /* 965 */,
0xE907C82E01CB8126 /* 966 */, 0xF8ED091913E37FCB /* 967 */,
0x3249D8F9C80046C9 /* 968 */, 0x80CF9BEDE388FB63 /* 969 */,
0x1881539A116CF19E /* 970 */, 0x5103F3F76BD52457 /* 971 */,
0x15B7E6F5AE47F7A8 /* 972 */, 0xDBD7C6DED47E9CCF /* 973 */,
0x44E55C410228BB1A /* 974 */, 0xB647D4255EDB4E99 /* 975 */,
0x5D11882BB8AAFC30 /* 976 */, 0xF5098BBB29D3212A /* 977 */,
0x8FB5EA14E90296B3 /* 978 */, 0x677B942157DD025A /* 979 */,
0xFB58E7C0A390ACB5 /* 980 */, 0x89D3674C83BD4A01 /* 981 */,
0x9E2DA4DF4BF3B93B /* 982 */, 0xFCC41E328CAB4829 /* 983 */,
0x03F38C96BA582C52 /* 984 */, 0xCAD1BDBD7FD85DB2 /* 985 */,
0xBBB442C16082AE83 /* 986 */, 0xB95FE86BA5DA9AB0 /* 987 */,
0xB22E04673771A93F /* 988 */, 0x845358C9493152D8 /* 989 */,
0xBE2A488697B4541E /* 990 */, 0x95A2DC2DD38E6966 /* 991 */,
0xC02C11AC923C852B /* 992 */, 0x2388B1990DF2A87B /* 993 */,
0x7C8008FA1B4F37BE /* 994 */, 0x1F70D0C84D54E503 /* 995 */,
0x5490ADEC7ECE57D4 /* 996 */, 0x002B3C27D9063A3A /* 997 */,
0x7EAEA3848030A2BF /* 998 */, 0xC602326DED2003C0 /* 999 */,
0x83A7287D69A94086 /* 1000 */, 0xC57A5FCB30F57A8A /* 1001 */,
0xB56844E479EBE779 /* 1002 */, 0xA373B40F05DCBCE9 /* 1003 */,
0xD71A786E88570EE2 /* 1004 */, 0x879CBACDBDE8F6A0 /* 1005 */,
0x976AD1BCC164A32F /* 1006 */, 0xAB21E25E9666D78B /* 1007 */,
0x901063AAE5E5C33C /* 1008 */, 0x9818B34448698D90 /* 1009 */,
0xE36487AE3E1E8ABB /* 1010 */, 0xAFBDF931893BDCB4 /* 1011 */,
0x6345A0DC5FBBD519 /* 1012 */, 0x8628FE269B9465CA /* 1013 */,
0x1E5D01603F9C51EC /* 1014 */, 0x4DE44006A15049B7 /* 1015 */,
0xBF6C70E5F776CBB1 /* 1016 */, 0x411218F2EF552BED /* 1017 */,
0xCB0C0708705A36A3 /* 1018 */, 0xE74D14754F986044 /* 1019 */,
0xCD56D9430EA8280E /* 1020 */, 0xC12591D7535F5065 /* 1021 */,
0xC83223F1720AEF96 /* 1022 */, 0xC3A0396F7363A51F /* 1023 */
];
}
}

View File

@@ -0,0 +1,185 @@
using System;
namespace SabreTools.Hashing.Tiger
{
/// <summary>
/// Reference implementation of the Tiger hash
/// </summary>
/// <see href="https://biham.cs.technion.ac.il/Reports/Tiger/"/>
public class TigerHash
{
/// <summary>
/// The number of passes of the hash function.
/// Three passes are recommended.
/// Use four passes when you need extra security.
/// Must be at least three.
/// </summary>
private const int PASSES = 3;
public void tiger(ulong[] str, ulong length)
{
ulong i, j;
byte[] temp = new byte[64];
ulong[] res =
[
0x0123456789ABCDEF,
0xFEDCBA9876543210,
0xF096A5B4C3B2E187
];
int strOffset = 0;
for (i = length; i >= 64; i -= 64)
{
Compress(str, strOffset, res);
strOffset += 8;
}
byte[] strBytes = new byte[str.Length * 8];
Array.ConstrainedCopy(str, 0, strBytes, 0, str.Length);
for (j = 0; j < i; j++)
{
temp[j] = strBytes[j];
}
temp[j++] = 0x01;
for (; (j & 7) > 0; j++)
{
temp[j] = 0;
}
if (j > 56)
{
for (; j < 64; j++)
{
temp[j] = 0;
}
Compress(ref temp, 0, res);
j = 0;
}
for (; j < 56; j++)
{
temp[j] = 0;
}
Compress(ref temp, 0, res, true, length);
}
private static bool Compress(ref byte[] str, int strOffset, ulong[] state, bool shouldSetSeven = false, ulong length = 0)
{
// Create the temp array
ulong[] temp = new ulong[str.Length / 8];
Array.ConstrainedCopy(str, 0, temp, 0, str.Length);
// Set index 7, if required
if (shouldSetSeven)
temp[7] = length << 3;
// Run the compression
bool success = Compress(temp, strOffset, state);
// Copy the values back
Array.ConstrainedCopy(temp, 0, str, 0, temp.Length);
return success;
}
private static bool Compress(ulong[] str, int strOffset, ulong[] state)
{
// Bounds checking
if (state.Length != 3)
return false;
if (str.Length < strOffset + 8)
return false;
ulong[] x = new ulong[8];
Array.Copy(str, strOffset, x, 0, 8);
// save_abc
ulong aa = state[0];
ulong bb = state[1];
ulong cc = state[2];
for (int pass_no = 0; pass_no < PASSES; pass_no++)
{
if (pass_no != 0)
KeySchedule(x);
int mul = pass_no == 0 ? 5 : pass_no == 1 ? 7 : 9;
Pass(state, x, mul);
ulong temp = state[0]; state[0] = state[2]; state[2] = state[1]; state[1] = temp;
}
// feedforward
state[0] ^= aa;
state[1] -= bb;
state[2] += cc;
return true;
}
private static void KeySchedule(ulong[] x)
{
x[0] -= x[7] ^ 0xA5A5A5A5A5A5A5A5;
x[1] ^= x[0];
x[2] += x[1];
x[3] -= x[2] ^ ((~x[1]) << 19);
x[4] ^= x[3];
x[5] += x[4];
x[6] -= x[5] ^ ((~x[4]) >> 23);
x[7] ^= x[6];
x[0] += x[7];
x[1] -= x[0] ^ ((~x[7]) << 19);
x[2] ^= x[1];
x[3] += x[2];
x[4] -= x[3] ^ ((~x[2]) >> 23);
x[5] ^= x[4];
x[6] += x[5];
x[7] -= x[6] ^ 0x0123456789ABCDEF;
}
private static bool Pass(ulong[] state, ulong[] x, int mul)
{
// Bounds checking
if (state.Length != 3)
return false;
Round(state, 0, 1, 2, x[0], mul);
Round(state, 1, 2, 0, x[1], mul);
Round(state, 2, 0, 1, x[2], mul);
Round(state, 0, 1, 2, x[3], mul);
Round(state, 1, 2, 0, x[4], mul);
Round(state, 2, 0, 1, x[5], mul);
Round(state, 0, 1, 2, x[6], mul);
Round(state, 1, 2, 0, x[7], mul);
return true;
}
private static bool Round(ulong[] state, int a, int b, int c, ulong x, int mul)
{
// Bounds checking
if (state.Length != 3)
return false;
state[c] ^= x;
state[a] -= t1((byte)state[c])
^ t2((byte)(((uint)state[c]) >> (2 * 8)))
^ t3((byte)((state[c]) >> (4 * 8)))
^ t4((byte)(((uint)((state[c]) >> (4 * 8))) >> (2 * 8)));
state[b] += t4((byte)(((uint)state[c]) >> (1 * 8)))
^ t3((byte)(((uint)state[c]) >> (3 * 8)))
^ t2((byte)(((uint)((state[c]) >> (4 * 8))) >> (1 * 8)))
^ t1((byte)(((uint)((state[c]) >> (4 * 8))) >> (3 * 8)));
state[b] *= (ulong)mul;
return true;
}
private static ulong t1(int offset) => SBoxes.Table[offset];
private static ulong t2(int offset) => SBoxes.Table[offset + 256];
private static ulong t3(int offset) => SBoxes.Table[offset + 256 * 2];
private static ulong t4(int offset) => SBoxes.Table[offset + 256 * 3];
}
}

36
publish-nix.sh Normal file
View File

@@ -0,0 +1,36 @@
#! /bin/bash
# This batch file assumes the following:
# - .NET 8.0 (or newer) SDK is installed and in PATH
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
# Optional parameters
NO_BUILD=false
while getopts "uba" OPTION
do
case $OPTION in
b)
NO_BUILD=true
;;
*)
echo "Invalid option provided"
exit 1
;;
esac
done
# Set the current directory as a variable
BUILD_FOLDER=$PWD
# Only build if requested
if [ $NO_BUILD = false ]
then
# Restore Nuget packages for all builds
echo "Restoring Nuget packages"
dotnet restore
# Create Nuget Package
dotnet pack SabreTools.Hashing/SabreTools.Hashing.csproj --output $BUILD_FOLDER
fi

26
publish-win.ps1 Normal file
View File

@@ -0,0 +1,26 @@
# This batch file assumes the following:
# - .NET 8.0 (or newer) SDK is installed and in PATH
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
# Optional parameters
param(
[Parameter(Mandatory = $false)]
[Alias("NoBuild")]
[switch]$NO_BUILD
)
# Set the current directory as a variable
$BUILD_FOLDER = $PSScriptRoot
# Only build if requested
if (!$NO_BUILD.IsPresent)
{
# Restore Nuget packages for all builds
Write-Host "Restoring Nuget packages"
dotnet restore
# Create Nuget Package
dotnet pack SabreTools.Hashing\SabreTools.Hashing.csproj --output $BUILD_FOLDER
}