mirror of
https://github.com/SabreTools/SabreTools.Hashing.git
synced 2026-02-08 05:37:51 +00:00
Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7eeb11261b | ||
|
|
a0fc83b617 | ||
|
|
fbc81459ee | ||
|
|
7d53e07e90 | ||
|
|
e83c31b89c | ||
|
|
ca08f97336 | ||
|
|
bd1e23dad4 | ||
|
|
b22f3d2743 | ||
|
|
23ed4e9849 | ||
|
|
4bc26b824f | ||
|
|
d5b0b2ad02 | ||
|
|
3fa3ece655 | ||
|
|
87fb62d772 | ||
|
|
ce9887ef19 | ||
|
|
dcd4555027 | ||
|
|
b11ded8756 | ||
|
|
28b33b67f8 | ||
|
|
cb7c84293d | ||
|
|
83c6346114 | ||
|
|
eef5fdc29b | ||
|
|
84d319867c | ||
|
|
83c69f895c | ||
|
|
826d629d98 | ||
|
|
6e8f13089e | ||
|
|
632b11ef2b | ||
|
|
c8f7497bf3 | ||
|
|
7dc19b8127 | ||
|
|
a3bca2abb4 | ||
|
|
c19509944b | ||
|
|
076686bc04 | ||
|
|
1aea60880a | ||
|
|
9e5cadd8d2 | ||
|
|
11c03d8a08 | ||
|
|
ff113dfcad | ||
|
|
fe9fe268c9 | ||
|
|
71a45e5cd9 | ||
|
|
f0c42d3707 | ||
|
|
3c31839ee2 | ||
|
|
3ddc4397de | ||
|
|
bf0cc50ded | ||
|
|
99d4b5d62f | ||
|
|
45adf3a8cd | ||
|
|
b5fc196018 | ||
|
|
fac3a5ab43 | ||
|
|
8face3e4ed | ||
|
|
047463f726 | ||
|
|
7ab41ce096 |
@@ -4,10 +4,11 @@ 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) | SpamSum | Some code tweaks made to support older .NET versions |
|
||||
| [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` |
|
||||
| [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 / OptimizedCRC](https://gitlab.com/eugene77/CRC32) | CRC-32 | Used in `net20`, `net35`, `net40`, and `net452` |
|
||||
| [System.IO.Hashing](https://www.nuget.org/packages/System.IO.Hashing) | CRC-32, CRC-64, xxHash32, xxHash64, XXH3, XXH128 | Used in `net462` and above |
|
||||
| [System.Security.Cryptography](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography) | MD5, SHA-1, SHA-256, SHA-384, SHA-512 | Built-in library |
|
||||
| [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.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).
|
||||
|
||||
58
SabreTools.Hashing.Test/CompressedStreamTests.cs
Normal file
58
SabreTools.Hashing.Test/CompressedStreamTests.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,23 +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 _crc32 = "ba02a660";
|
||||
private const string _crc64 = "a0e0009c18b5338d";
|
||||
private const string _md5 = "b722871eaa950016296184d026c5dec9";
|
||||
private const string _sha1 = "eea1ee2d801d830c4bdad4df3c8da6f9f52d1a9f";
|
||||
private const string _sha256 = "fdb02dee8c319c52087382c45f099c90d0b6cc824850aff28c1bfb2884b7b855";
|
||||
private const string _sha384 = "e276c49618fff25bc1fe2e0659cd0ef0e7c1186563b063e07c52323b9899f3ce9b091be04d6208444b3ef1265e879074";
|
||||
private const string _sha512 = "15d69514eb628c2403e945a7cafd1d27e557f6e336c69b63ea17e7ed9d256cc374ee662f09305836d6de37fdae59d83883b982aa8446e4ff26346b6b6b50b240";
|
||||
private const string _spamsum = "3:hMCPQCE6AFQxWyENFACBE+rW6Tj7SMQmKozr9MVERkL:hZRdxZENFs+rPSromekL";
|
||||
private const string _xxhash32 = "8e331daa";
|
||||
private const string _xxhash64 = "082bf6f0a49e1e18";
|
||||
private const string _xxhash3 = "040474eb0eda9ff2";
|
||||
private const string _xxhash128 = "d934b4b4a5e1e11baeef8012fbcd11e8";
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -42,63 +37,23 @@ namespace SabreTools.Hashing.Test
|
||||
public void GetFileHashesTest()
|
||||
{
|
||||
var hashDict = HashTool.GetFileHashes(_hashFilePath);
|
||||
|
||||
Assert.NotNull(hashDict);
|
||||
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
|
||||
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
|
||||
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]);
|
||||
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
|
||||
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
|
||||
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
|
||||
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
|
||||
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
|
||||
TestHelper.ValidateHashes(hashDict);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetFileHashesAndSizeTest()
|
||||
{
|
||||
var hashDict = HashTool.GetFileHashesAndSize(_hashFilePath, out long actualSize);
|
||||
|
||||
Assert.Equal(_hashFileSize, actualSize);
|
||||
Assert.NotNull(hashDict);
|
||||
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
|
||||
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
|
||||
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
|
||||
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]);
|
||||
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
|
||||
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
|
||||
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
|
||||
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
|
||||
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
|
||||
TestHelper.ValidateHashes(hashDict);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void GetByteArrayHashesTest()
|
||||
{
|
||||
byte[] fileBytes = File.ReadAllBytes(_hashFilePath);
|
||||
var hashDict = HashTool.GetByteArrayHashes(fileBytes);
|
||||
|
||||
Assert.NotNull(hashDict);
|
||||
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
|
||||
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
|
||||
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]);
|
||||
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
|
||||
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
|
||||
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
|
||||
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
|
||||
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
|
||||
TestHelper.ValidateHashes(hashDict);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -106,20 +61,7 @@ namespace SabreTools.Hashing.Test
|
||||
{
|
||||
var fileStream = File.OpenRead(_hashFilePath);
|
||||
var hashDict = HashTool.GetStreamHashes(fileStream);
|
||||
|
||||
Assert.NotNull(hashDict);
|
||||
Assert.Equal(_crc32, hashDict[HashType.CRC32]);
|
||||
Assert.Equal(_crc64, hashDict[HashType.CRC64]);
|
||||
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]);
|
||||
Assert.Equal(_spamsum, hashDict[HashType.SpamSum]);
|
||||
Assert.Equal(_xxhash32, hashDict[HashType.XxHash32]);
|
||||
Assert.Equal(_xxhash64, hashDict[HashType.XxHash64]);
|
||||
Assert.Equal(_xxhash3, hashDict[HashType.XxHash3]);
|
||||
Assert.Equal(_xxhash128, hashDict[HashType.XxHash128]);
|
||||
TestHelper.ValidateHashes(hashDict);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
||||
<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>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -16,12 +19,9 @@
|
||||
</Content>
|
||||
</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" />
|
||||
<!-- Support for old .NET versions -->
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net462`)) OR $(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
|
||||
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
|
||||
<PackageReference Include="xunit" Version="2.6.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
@@ -29,6 +29,14 @@
|
||||
</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>
|
||||
|
||||
BIN
SabreTools.Hashing.Test/TestData/file-to-hash-multi.zip
Normal file
BIN
SabreTools.Hashing.Test/TestData/file-to-hash-multi.zip
Normal file
Binary file not shown.
BIN
SabreTools.Hashing.Test/TestData/file-to-hash.bin.gz
Normal file
BIN
SabreTools.Hashing.Test/TestData/file-to-hash.bin.gz
Normal file
Binary file not shown.
BIN
SabreTools.Hashing.Test/TestData/file-to-hash.zip
Normal file
BIN
SabreTools.Hashing.Test/TestData/file-to-hash.zip
Normal file
Binary file not shown.
97
SabreTools.Hashing.Test/TestHelper.cs
Normal file
97
SabreTools.Hashing.Test/TestHelper.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.Hashing.Test
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class for tests
|
||||
/// </summary>
|
||||
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_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
|
||||
|
||||
/// <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_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
|
||||
}
|
||||
}
|
||||
}
|
||||
217
SabreTools.Hashing/Aaru.Checksums/Adler32/neon.cs
Normal file
217
SabreTools.Hashing/Aaru.Checksums/Adler32/neon.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : neon.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
// The Chromium Authors
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Compute Adler32 checksum using NEON vectorization.
|
||||
//
|
||||
// --[ 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.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
|
||||
namespace Aaru.Checksums.Adler32;
|
||||
|
||||
static class Neon
|
||||
{
|
||||
internal static void Step(ref ushort preSum1, ref ushort preSum2, byte[] buf, uint len)
|
||||
{
|
||||
/*
|
||||
* Split Adler-32 into component sums.
|
||||
*/
|
||||
uint s1 = preSum1;
|
||||
uint s2 = preSum2;
|
||||
|
||||
var bufPos = 0;
|
||||
|
||||
/*
|
||||
* Process the data in blocks.
|
||||
*/
|
||||
const uint blockSize = 1 << 5;
|
||||
uint blocks = len / blockSize;
|
||||
len -= blocks * blockSize;
|
||||
|
||||
while(blocks != 0)
|
||||
{
|
||||
uint n = Adler32Context.NMAX / blockSize; /* The NMAX constraint. */
|
||||
|
||||
if(n > blocks)
|
||||
n = blocks;
|
||||
|
||||
blocks -= n;
|
||||
/*
|
||||
* Process n blocks of data. At most NMAX data bytes can be
|
||||
* processed before s2 must be reduced modulo ADLER_MODULE.
|
||||
*/
|
||||
var vS2 = Vector128.Create(s1 * n, 0, 0, 0);
|
||||
var vS1 = Vector128.Create(0u, 0, 0, 0);
|
||||
Vector128<ushort> vColumnSum1 = AdvSimd.DuplicateToVector128((ushort)0);
|
||||
Vector128<ushort> vColumnSum2 = AdvSimd.DuplicateToVector128((ushort)0);
|
||||
Vector128<ushort> vColumnSum3 = AdvSimd.DuplicateToVector128((ushort)0);
|
||||
Vector128<ushort> vColumnSum4 = AdvSimd.DuplicateToVector128((ushort)0);
|
||||
|
||||
do
|
||||
{
|
||||
/*
|
||||
* Load 32 input bytes.
|
||||
*/
|
||||
var bytes1 = Vector128.Create(buf[bufPos], buf[bufPos + 1], buf[bufPos + 2], buf[bufPos + 3],
|
||||
buf[bufPos + 4], buf[bufPos + 5], buf[bufPos + 6], buf[bufPos + 7],
|
||||
buf[bufPos + 8], buf[bufPos + 9], buf[bufPos + 10], buf[bufPos + 11],
|
||||
buf[bufPos + 12], buf[bufPos + 13], buf[bufPos + 14], buf[bufPos + 15]);
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
var bytes2 = Vector128.Create(buf[bufPos], buf[bufPos + 1], buf[bufPos + 2], buf[bufPos + 3],
|
||||
buf[bufPos + 4], buf[bufPos + 5], buf[bufPos + 6], buf[bufPos + 7],
|
||||
buf[bufPos + 8], buf[bufPos + 9], buf[bufPos + 10], buf[bufPos + 11],
|
||||
buf[bufPos + 12], buf[bufPos + 13], buf[bufPos + 14], buf[bufPos + 15]);
|
||||
|
||||
bufPos += 16;
|
||||
/*
|
||||
* Add previous block byte sum to v_s2.
|
||||
*/
|
||||
vS2 = AdvSimd.Add(vS2, vS1);
|
||||
|
||||
/*
|
||||
* Horizontally add the bytes for s1.
|
||||
*/
|
||||
vS1 =
|
||||
AdvSimd.AddPairwiseWideningAndAdd(vS1,
|
||||
AdvSimd.
|
||||
AddPairwiseWideningAndAdd(AdvSimd.AddPairwiseWidening(bytes1),
|
||||
bytes2));
|
||||
|
||||
/*
|
||||
* Vertically add the bytes for s2.
|
||||
*/
|
||||
vColumnSum1 = AdvSimd.AddWideningLower(vColumnSum1, bytes1.GetLower());
|
||||
vColumnSum2 = AdvSimd.AddWideningLower(vColumnSum2, bytes1.GetUpper());
|
||||
vColumnSum3 = AdvSimd.AddWideningLower(vColumnSum3, bytes2.GetLower());
|
||||
vColumnSum4 = AdvSimd.AddWideningLower(vColumnSum4, bytes2.GetUpper());
|
||||
} while(--n != 0);
|
||||
|
||||
vS2 = AdvSimd.ShiftLeftLogical(vS2, 5);
|
||||
|
||||
/*
|
||||
* Multiply-add bytes by [ 32, 31, 30, ... ] for s2.
|
||||
*/
|
||||
vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum1.GetLower(),
|
||||
Vector64.Create((ushort)32, 31, 30, 29));
|
||||
|
||||
vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum1.GetUpper(),
|
||||
Vector64.Create((ushort)28, 27, 26, 25));
|
||||
|
||||
vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum2.GetLower(),
|
||||
Vector64.Create((ushort)24, 23, 22, 21));
|
||||
|
||||
vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum2.GetUpper(),
|
||||
Vector64.Create((ushort)20, 19, 18, 17));
|
||||
|
||||
vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum3.GetLower(),
|
||||
Vector64.Create((ushort)16, 15, 14, 13));
|
||||
|
||||
vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum3.GetUpper(),
|
||||
Vector64.Create((ushort)12, 11, 10, 9));
|
||||
|
||||
vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum4.GetLower(), Vector64.Create((ushort)8, 7, 6, 5));
|
||||
|
||||
vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum4.GetUpper(), Vector64.Create((ushort)4, 3, 2, 1));
|
||||
|
||||
/*
|
||||
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
|
||||
*/
|
||||
Vector64<uint> sum1 = AdvSimd.AddPairwise(vS1.GetLower(), vS1.GetUpper());
|
||||
Vector64<uint> sum2 = AdvSimd.AddPairwise(vS2.GetLower(), vS2.GetUpper());
|
||||
Vector64<uint> s1S2 = AdvSimd.AddPairwise(sum1, sum2);
|
||||
s1 += AdvSimd.Extract(s1S2, 0);
|
||||
s2 += AdvSimd.Extract(s1S2, 1);
|
||||
/*
|
||||
* Reduce.
|
||||
*/
|
||||
s1 %= Adler32Context.ADLER_MODULE;
|
||||
s2 %= Adler32Context.ADLER_MODULE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle leftover data.
|
||||
*/
|
||||
if(len != 0)
|
||||
{
|
||||
if(len >= 16)
|
||||
{
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
len -= 16;
|
||||
}
|
||||
|
||||
while(len-- != 0)
|
||||
s2 += s1 += buf[bufPos++];
|
||||
|
||||
if(s1 >= Adler32Context.ADLER_MODULE)
|
||||
s1 -= Adler32Context.ADLER_MODULE;
|
||||
|
||||
s2 %= Adler32Context.ADLER_MODULE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the recombined sums.
|
||||
*/
|
||||
preSum1 = (ushort)(s1 & 0xFFFF);
|
||||
preSum2 = (ushort)(s2 & 0xFFFF);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
194
SabreTools.Hashing/Aaru.Checksums/Adler32/ssse3.cs
Normal file
194
SabreTools.Hashing/Aaru.Checksums/Adler32/ssse3.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : ssse3.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
// The Chromium Authors
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Compute Adler32 checksum using SSSE3 vectorization.
|
||||
//
|
||||
// --[ 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 NETCOREAPP3_1_OR_GREATER
|
||||
using System;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
|
||||
namespace Aaru.Checksums.Adler32;
|
||||
|
||||
static class Ssse3
|
||||
{
|
||||
internal static void Step(ref ushort sum1, ref ushort sum2, byte[] buf, uint len)
|
||||
{
|
||||
uint s1 = sum1;
|
||||
uint s2 = sum2;
|
||||
var bufPos = 0;
|
||||
|
||||
/*
|
||||
* Process the data in blocks.
|
||||
*/
|
||||
const uint blockSize = 1 << 5;
|
||||
uint blocks = len / blockSize;
|
||||
len -= blocks * blockSize;
|
||||
|
||||
while(blocks != 0)
|
||||
{
|
||||
uint n = Adler32Context.NMAX / blockSize; /* The NMAX constraint. */
|
||||
|
||||
if(n > blocks)
|
||||
n = blocks;
|
||||
|
||||
blocks -= n;
|
||||
|
||||
Vector128<byte> tap1 = Vector128.Create(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17).
|
||||
AsByte();
|
||||
|
||||
Vector128<byte> tap2 = Vector128.Create(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1).AsByte();
|
||||
Vector128<byte> zero = Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).AsByte();
|
||||
var ones = Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1);
|
||||
/*
|
||||
* Process n blocks of data. At most NMAX data bytes can be
|
||||
* processed before s2 must be reduced modulo BASE.
|
||||
*/
|
||||
var vPs = Vector128.Create(s1 * n, 0, 0, 0);
|
||||
var vS2 = Vector128.Create(s2, 0, 0, 0);
|
||||
var vS1 = Vector128.Create(0u, 0, 0, 0);
|
||||
|
||||
do
|
||||
{
|
||||
/*
|
||||
* Load 32 input bytes.
|
||||
*/
|
||||
var bytes1 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
|
||||
BitConverter.ToUInt32(buf, bufPos + 4),
|
||||
BitConverter.ToUInt32(buf, bufPos + 8),
|
||||
BitConverter.ToUInt32(buf, bufPos + 12));
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
var bytes2 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
|
||||
BitConverter.ToUInt32(buf, bufPos + 4),
|
||||
BitConverter.ToUInt32(buf, bufPos + 8),
|
||||
BitConverter.ToUInt32(buf, bufPos + 12));
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
/*
|
||||
* Add previous block byte sum to v_ps.
|
||||
*/
|
||||
vPs = Sse2.Add(vPs, vS1);
|
||||
/*
|
||||
* Horizontally add the bytes for s1, multiply-adds the
|
||||
* bytes by [ 32, 31, 30, ... ] for s2.
|
||||
*/
|
||||
vS1 = Sse2.Add(vS1, Sse2.SumAbsoluteDifferences(bytes1.AsByte(), zero).AsUInt32());
|
||||
|
||||
Vector128<short> mad1 =
|
||||
System.Runtime.Intrinsics.X86.Ssse3.MultiplyAddAdjacent(bytes1.AsByte(), tap1.AsSByte());
|
||||
|
||||
vS2 = Sse2.Add(vS2, Sse2.MultiplyAddAdjacent(mad1.AsInt16(), ones.AsInt16()).AsUInt32());
|
||||
vS1 = Sse2.Add(vS1, Sse2.SumAbsoluteDifferences(bytes2.AsByte(), zero).AsUInt32());
|
||||
|
||||
Vector128<short> mad2 =
|
||||
System.Runtime.Intrinsics.X86.Ssse3.MultiplyAddAdjacent(bytes2.AsByte(), tap2.AsSByte());
|
||||
|
||||
vS2 = Sse2.Add(vS2, Sse2.MultiplyAddAdjacent(mad2.AsInt16(), ones.AsInt16()).AsUInt32());
|
||||
} while(--n != 0);
|
||||
|
||||
vS2 = Sse2.Add(vS2, Sse2.ShiftLeftLogical(vPs, 5));
|
||||
/*
|
||||
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
|
||||
*/
|
||||
vS1 = Sse2.Add(vS1, Sse2.Shuffle(vS1, 177));
|
||||
vS1 = Sse2.Add(vS1, Sse2.Shuffle(vS1, 78));
|
||||
s1 += (uint)Sse2.ConvertToInt32(vS1.AsInt32());
|
||||
vS2 = Sse2.Add(vS2, Sse2.Shuffle(vS2, 177));
|
||||
vS2 = Sse2.Add(vS2, Sse2.Shuffle(vS2, 78));
|
||||
s2 = (uint)Sse2.ConvertToInt32(vS2.AsInt32());
|
||||
/*
|
||||
* Reduce.
|
||||
*/
|
||||
s1 %= Adler32Context.ADLER_MODULE;
|
||||
s2 %= Adler32Context.ADLER_MODULE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle leftover data.
|
||||
*/
|
||||
if(len != 0)
|
||||
{
|
||||
if(len >= 16)
|
||||
{
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
len -= 16;
|
||||
}
|
||||
|
||||
while(len-- != 0)
|
||||
s2 += s1 += buf[bufPos++];
|
||||
|
||||
if(s1 >= Adler32Context.ADLER_MODULE)
|
||||
s1 -= Adler32Context.ADLER_MODULE;
|
||||
|
||||
s2 %= Adler32Context.ADLER_MODULE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the recombined sums.
|
||||
*/
|
||||
sum1 = (ushort)(s1 & 0xFFFF);
|
||||
sum2 = (ushort)(s2 & 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
434
SabreTools.Hashing/Aaru.Checksums/Adler32Context.cs
Normal file
434
SabreTools.Hashing/Aaru.Checksums/Adler32Context.cs
Normal file
@@ -0,0 +1,434 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : Adler32Context.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Implements an Adler-32 algorithm.
|
||||
//
|
||||
// --[ 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) 1995-2011 Mark Adler
|
||||
// Copyright (C) Jean-loup Gailly
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
#endif
|
||||
using System.Text;
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
using Aaru.Checksums.Adler32;
|
||||
#endif
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Helpers;
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
using Ssse3 = System.Runtime.Intrinsics.X86.Ssse3;
|
||||
#endif
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Implements the Adler-32 algorithm</summary>
|
||||
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||
public sealed class Adler32Context : IChecksum
|
||||
{
|
||||
internal const ushort ADLER_MODULE = 65521;
|
||||
internal const uint NMAX = 5552;
|
||||
readonly IntPtr _nativeContext;
|
||||
readonly bool _useNative;
|
||||
ushort _sum1, _sum2;
|
||||
|
||||
/// <summary>Initializes the Adler-32 sums</summary>
|
||||
public Adler32Context()
|
||||
{
|
||||
_sum1 = 1;
|
||||
_sum2 = 0;
|
||||
|
||||
if(!Native.IsSupported)
|
||||
return;
|
||||
|
||||
_nativeContext = adler32_init();
|
||||
_useNative = _nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Adler-32";
|
||||
|
||||
/// <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) => Step(ref _sum1, ref _sum2, data, len, _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()
|
||||
{
|
||||
var finalSum = (uint)(_sum2 << 16 | _sum1);
|
||||
|
||||
if(!_useNative)
|
||||
return BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
adler32_final(_nativeContext, ref finalSum);
|
||||
adler32_free(_nativeContext);
|
||||
|
||||
return BigEndianBitConverter.GetBytes(finalSum);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
var finalSum = (uint)(_sum2 << 16 | _sum1);
|
||||
|
||||
if(_useNative)
|
||||
{
|
||||
adler32_final(_nativeContext, ref finalSum);
|
||||
adler32_free(_nativeContext);
|
||||
}
|
||||
|
||||
var adlerOutput = new StringBuilder();
|
||||
|
||||
for(var i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
|
||||
adlerOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
|
||||
|
||||
return adlerOutput.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern IntPtr adler32_init();
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern int adler32_update(IntPtr ctx, byte[] data, uint len);
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern int adler32_final(IntPtr ctx, ref uint checksum);
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern void adler32_free(IntPtr ctx);
|
||||
|
||||
static void Step(ref ushort preSum1, ref ushort preSum2, byte[] data, uint len, bool useNative,
|
||||
IntPtr nativeContext)
|
||||
{
|
||||
if(useNative)
|
||||
{
|
||||
adler32_update(nativeContext, data, len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
if(Ssse3.IsSupported)
|
||||
{
|
||||
Adler32.Ssse3.Step(ref preSum1, ref preSum2, data, len);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
if(AdvSimd.IsSupported)
|
||||
{
|
||||
Neon.Step(ref preSum1, ref preSum2, data, len);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint sum1 = preSum1;
|
||||
uint sum2 = preSum2;
|
||||
var dataOff = 0;
|
||||
|
||||
switch(len)
|
||||
{
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
case 1:
|
||||
{
|
||||
sum1 += data[dataOff];
|
||||
|
||||
if(sum1 >= ADLER_MODULE)
|
||||
sum1 -= ADLER_MODULE;
|
||||
|
||||
sum2 += sum1;
|
||||
|
||||
if(sum2 >= ADLER_MODULE)
|
||||
sum2 -= ADLER_MODULE;
|
||||
|
||||
preSum1 = (ushort)(sum1 & 0xFFFF);
|
||||
preSum2 = (ushort)(sum2 & 0xFFFF);
|
||||
|
||||
return;
|
||||
}
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
case < 16:
|
||||
{
|
||||
while(len-- > 0)
|
||||
{
|
||||
sum1 += data[dataOff++];
|
||||
sum2 += sum1;
|
||||
}
|
||||
|
||||
if(sum1 >= ADLER_MODULE)
|
||||
sum1 -= ADLER_MODULE;
|
||||
|
||||
sum2 %= ADLER_MODULE; /* only added so many ADLER_MODULE's */
|
||||
preSum1 = (ushort)(sum1 & 0xFFFF);
|
||||
preSum2 = (ushort)(sum2 & 0xFFFF);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while(len >= NMAX)
|
||||
{
|
||||
len -= NMAX;
|
||||
uint n = NMAX / 16;
|
||||
|
||||
do
|
||||
{
|
||||
sum1 += data[dataOff];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
|
||||
/* 16 sums unrolled */
|
||||
dataOff += 16;
|
||||
} while(--n != 0);
|
||||
|
||||
sum1 %= ADLER_MODULE;
|
||||
sum2 %= ADLER_MODULE;
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if(len != 0)
|
||||
{
|
||||
/* avoid modulos if none remaining */
|
||||
while(len >= 16)
|
||||
{
|
||||
len -= 16;
|
||||
sum1 += data[dataOff];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
|
||||
dataOff += 16;
|
||||
}
|
||||
|
||||
while(len-- != 0)
|
||||
{
|
||||
sum1 += data[dataOff++];
|
||||
sum2 += sum1;
|
||||
}
|
||||
|
||||
sum1 %= ADLER_MODULE;
|
||||
sum2 %= ADLER_MODULE;
|
||||
}
|
||||
|
||||
preSum1 = (ushort)(sum1 & 0xFFFF);
|
||||
preSum2 = (ushort)(sum2 & 0xFFFF);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
nativeContext = adler32_init();
|
||||
|
||||
if(nativeContext == IntPtr.Zero)
|
||||
useNative = false;
|
||||
}
|
||||
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
|
||||
ushort localSum1 = 1;
|
||||
ushort localSum2 = 0;
|
||||
|
||||
var buffer = new byte[65536];
|
||||
int read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
|
||||
while(read > 0)
|
||||
{
|
||||
Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
|
||||
read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
}
|
||||
|
||||
var finalSum = (uint)(localSum2 << 16 | localSum1);
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
adler32_final(nativeContext, ref finalSum);
|
||||
adler32_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
var adlerOutput = new StringBuilder();
|
||||
|
||||
foreach(byte h in hash)
|
||||
adlerOutput.Append(h.ToString("x2"));
|
||||
|
||||
fileStream.Close();
|
||||
|
||||
return adlerOutput.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)
|
||||
{
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
nativeContext = adler32_init();
|
||||
|
||||
if(nativeContext == IntPtr.Zero)
|
||||
useNative = false;
|
||||
}
|
||||
|
||||
ushort localSum1 = 1;
|
||||
ushort localSum2 = 0;
|
||||
|
||||
Step(ref localSum1, ref localSum2, data, len, useNative, nativeContext);
|
||||
|
||||
var finalSum = (uint)(localSum2 << 16 | localSum1);
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
adler32_final(nativeContext, ref finalSum);
|
||||
adler32_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
var adlerOutput = new StringBuilder();
|
||||
|
||||
foreach(byte h in hash)
|
||||
adlerOutput.Append(h.ToString("x2"));
|
||||
|
||||
return adlerOutput.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);
|
||||
}
|
||||
274
SabreTools.Hashing/Aaru.Checksums/CRC16CCITTContext.cs
Normal file
274
SabreTools.Hashing/Aaru.Checksums/CRC16CCITTContext.cs
Normal file
@@ -0,0 +1,274 @@
|
||||
// /***************************************************************************
|
||||
// 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);
|
||||
}
|
||||
649
SabreTools.Hashing/Aaru.Checksums/CRC16Context.cs
Normal file
649
SabreTools.Hashing/Aaru.Checksums/CRC16Context.cs
Normal file
@@ -0,0 +1,649 @@
|
||||
// /***************************************************************************
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
276
SabreTools.Hashing/Aaru.Checksums/CRC16IBMContext.cs
Normal file
276
SabreTools.Hashing/Aaru.Checksums/CRC16IBMContext.cs
Normal file
@@ -0,0 +1,276 @@
|
||||
// /***************************************************************************
|
||||
// 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);
|
||||
}
|
||||
136
SabreTools.Hashing/Aaru.Checksums/CRC32/arm_simd.cs
Normal file
136
SabreTools.Hashing/Aaru.Checksums/CRC32/arm_simd.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
// /***************************************************************************
|
||||
// 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
|
||||
227
SabreTools.Hashing/Aaru.Checksums/CRC32/clmul.cs
Normal file
227
SabreTools.Hashing/Aaru.Checksums/CRC32/clmul.cs
Normal file
@@ -0,0 +1,227 @@
|
||||
// /***************************************************************************
|
||||
// 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
|
||||
671
SabreTools.Hashing/Aaru.Checksums/CRC32Context.cs
Normal file
671
SabreTools.Hashing/Aaru.Checksums/CRC32Context.cs
Normal file
@@ -0,0 +1,671 @@
|
||||
// /***************************************************************************
|
||||
// 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);
|
||||
}
|
||||
111
SabreTools.Hashing/Aaru.Checksums/CRC64/clmul.cs
Normal file
111
SabreTools.Hashing/Aaru.Checksums/CRC64/clmul.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
// /***************************************************************************
|
||||
// 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
|
||||
608
SabreTools.Hashing/Aaru.Checksums/CRC64Context.cs
Normal file
608
SabreTools.Hashing/Aaru.Checksums/CRC64Context.cs
Normal file
@@ -0,0 +1,608 @@
|
||||
// /***************************************************************************
|
||||
// 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);
|
||||
}
|
||||
219
SabreTools.Hashing/Aaru.Checksums/Fletcher32/neon.cs
Normal file
219
SabreTools.Hashing/Aaru.Checksums/Fletcher32/neon.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : neon.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
// The Chromium Authors
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Compute Fletcher32 checksum using NEON vectorization.
|
||||
//
|
||||
// --[ 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.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
|
||||
namespace Aaru.Checksums.Fletcher32;
|
||||
|
||||
static class Neon
|
||||
{
|
||||
internal static void Step(ref ushort preSum1, ref ushort preSum2, byte[] buf, uint len)
|
||||
{
|
||||
/*
|
||||
* Split Fletcher-32 into component sums.
|
||||
*/
|
||||
uint s1 = preSum1;
|
||||
uint s2 = preSum2;
|
||||
|
||||
var bufPos = 0;
|
||||
|
||||
/*
|
||||
* Process the data in blocks.
|
||||
*/
|
||||
const uint block_Size = 1 << 5;
|
||||
uint blocks = len / block_Size;
|
||||
len -= blocks * block_Size;
|
||||
|
||||
while(blocks != 0)
|
||||
{
|
||||
uint n = Fletcher32Context.NMAX / block_Size; /* The NMAX constraint. */
|
||||
|
||||
if(n > blocks)
|
||||
n = blocks;
|
||||
|
||||
blocks -= n;
|
||||
/*
|
||||
* Process n blocks of data. At most NMAX data bytes can be
|
||||
* processed before s2 must be reduced modulo FLETCHER_MODULE.
|
||||
*/
|
||||
var v_S2 = Vector128.Create(s1 * n, 0, 0, 0);
|
||||
var v_S1 = Vector128.Create(0u, 0, 0, 0);
|
||||
Vector128<ushort> v_Column_Sum_1 = AdvSimd.DuplicateToVector128((ushort)0);
|
||||
Vector128<ushort> v_Column_Sum_2 = AdvSimd.DuplicateToVector128((ushort)0);
|
||||
Vector128<ushort> v_Column_Sum_3 = AdvSimd.DuplicateToVector128((ushort)0);
|
||||
Vector128<ushort> v_Column_Sum_4 = AdvSimd.DuplicateToVector128((ushort)0);
|
||||
|
||||
do
|
||||
{
|
||||
/*
|
||||
* Load 32 input bytes.
|
||||
*/
|
||||
var bytes1 = Vector128.Create(buf[bufPos], buf[bufPos + 1], buf[bufPos + 2], buf[bufPos + 3],
|
||||
buf[bufPos + 4], buf[bufPos + 5], buf[bufPos + 6], buf[bufPos + 7],
|
||||
buf[bufPos + 8], buf[bufPos + 9], buf[bufPos + 10], buf[bufPos + 11],
|
||||
buf[bufPos + 12], buf[bufPos + 13], buf[bufPos + 14], buf[bufPos + 15]);
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
var bytes2 = Vector128.Create(buf[bufPos], buf[bufPos + 1], buf[bufPos + 2], buf[bufPos + 3],
|
||||
buf[bufPos + 4], buf[bufPos + 5], buf[bufPos + 6], buf[bufPos + 7],
|
||||
buf[bufPos + 8], buf[bufPos + 9], buf[bufPos + 10], buf[bufPos + 11],
|
||||
buf[bufPos + 12], buf[bufPos + 13], buf[bufPos + 14], buf[bufPos + 15]);
|
||||
|
||||
bufPos += 16;
|
||||
/*
|
||||
* Add previous block byte sum to v_s2.
|
||||
*/
|
||||
v_S2 = AdvSimd.Add(v_S2, v_S1);
|
||||
|
||||
/*
|
||||
* Horizontally add the bytes for s1.
|
||||
*/
|
||||
v_S1 =
|
||||
AdvSimd.AddPairwiseWideningAndAdd(v_S1,
|
||||
AdvSimd.
|
||||
AddPairwiseWideningAndAdd(AdvSimd.AddPairwiseWidening(bytes1),
|
||||
bytes2));
|
||||
|
||||
/*
|
||||
* Vertically add the bytes for s2.
|
||||
*/
|
||||
v_Column_Sum_1 = AdvSimd.AddWideningLower(v_Column_Sum_1, bytes1.GetLower());
|
||||
v_Column_Sum_2 = AdvSimd.AddWideningLower(v_Column_Sum_2, bytes1.GetUpper());
|
||||
v_Column_Sum_3 = AdvSimd.AddWideningLower(v_Column_Sum_3, bytes2.GetLower());
|
||||
v_Column_Sum_4 = AdvSimd.AddWideningLower(v_Column_Sum_4, bytes2.GetUpper());
|
||||
} while(--n != 0);
|
||||
|
||||
v_S2 = AdvSimd.ShiftLeftLogical(v_S2, 5);
|
||||
|
||||
/*
|
||||
* Multiply-add bytes by [ 32, 31, 30, ... ] for s2.
|
||||
*/
|
||||
v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2, v_Column_Sum_1.GetLower(),
|
||||
Vector64.Create((ushort)32, 31, 30, 29));
|
||||
|
||||
v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2, v_Column_Sum_1.GetUpper(),
|
||||
Vector64.Create((ushort)28, 27, 26, 25));
|
||||
|
||||
v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2, v_Column_Sum_2.GetLower(),
|
||||
Vector64.Create((ushort)24, 23, 22, 21));
|
||||
|
||||
v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2, v_Column_Sum_2.GetUpper(),
|
||||
Vector64.Create((ushort)20, 19, 18, 17));
|
||||
|
||||
v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2, v_Column_Sum_3.GetLower(),
|
||||
Vector64.Create((ushort)16, 15, 14, 13));
|
||||
|
||||
v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2, v_Column_Sum_3.GetUpper(),
|
||||
Vector64.Create((ushort)12, 11, 10, 9));
|
||||
|
||||
v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2, v_Column_Sum_4.GetLower(),
|
||||
Vector64.Create((ushort)8, 7, 6, 5));
|
||||
|
||||
v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2, v_Column_Sum_4.GetUpper(),
|
||||
Vector64.Create((ushort)4, 3, 2, 1));
|
||||
|
||||
/*
|
||||
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
|
||||
*/
|
||||
Vector64<uint> sum1 = AdvSimd.AddPairwise(v_S1.GetLower(), v_S1.GetUpper());
|
||||
Vector64<uint> sum2 = AdvSimd.AddPairwise(v_S2.GetLower(), v_S2.GetUpper());
|
||||
Vector64<uint> s1S2 = AdvSimd.AddPairwise(sum1, sum2);
|
||||
s1 += AdvSimd.Extract(s1S2, 0);
|
||||
s2 += AdvSimd.Extract(s1S2, 1);
|
||||
/*
|
||||
* Reduce.
|
||||
*/
|
||||
s1 %= Fletcher32Context.FLETCHER_MODULE;
|
||||
s2 %= Fletcher32Context.FLETCHER_MODULE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle leftover data.
|
||||
*/
|
||||
if(len != 0)
|
||||
{
|
||||
if(len >= 16)
|
||||
{
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
len -= 16;
|
||||
}
|
||||
|
||||
while(len-- != 0)
|
||||
s2 += s1 += buf[bufPos++];
|
||||
|
||||
if(s1 >= Fletcher32Context.FLETCHER_MODULE)
|
||||
s1 -= Fletcher32Context.FLETCHER_MODULE;
|
||||
|
||||
s2 %= Fletcher32Context.FLETCHER_MODULE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the recombined sums.
|
||||
*/
|
||||
preSum1 = (ushort)(s1 & 0xFFFF);
|
||||
preSum2 = (ushort)(s2 & 0xFFFF);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
193
SabreTools.Hashing/Aaru.Checksums/Fletcher32/ssse3.cs
Normal file
193
SabreTools.Hashing/Aaru.Checksums/Fletcher32/ssse3.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : ssse3.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
// The Chromium Authors
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Compute Fletcher32 checksum using SSSE3 vectorization.
|
||||
//
|
||||
// --[ 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 NETCOREAPP3_1_OR_GREATER
|
||||
using System;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
|
||||
namespace Aaru.Checksums.Fletcher32;
|
||||
|
||||
static class Ssse3
|
||||
{
|
||||
internal static void Step(ref ushort sum1, ref ushort sum2, byte[] buf, uint len)
|
||||
{
|
||||
uint s1 = sum1;
|
||||
uint s2 = sum2;
|
||||
var bufPos = 0;
|
||||
|
||||
/*
|
||||
* Process the data in blocks.
|
||||
*/
|
||||
const uint block_Size = 1 << 5;
|
||||
uint blocks = len / block_Size;
|
||||
len -= blocks * block_Size;
|
||||
|
||||
while(blocks != 0)
|
||||
{
|
||||
uint n = Fletcher32Context.NMAX / block_Size; /* The NMAX constraint. */
|
||||
|
||||
if(n > blocks)
|
||||
n = blocks;
|
||||
|
||||
blocks -= n;
|
||||
|
||||
Vector128<byte> tap1 = Vector128.Create(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17).
|
||||
AsByte();
|
||||
|
||||
Vector128<byte> tap2 = Vector128.Create(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1).AsByte();
|
||||
Vector128<byte> zero = Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).AsByte();
|
||||
var ones = Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1);
|
||||
/*
|
||||
* Process n blocks of data. At most NMAX data bytes can be
|
||||
* processed before s2 must be reduced modulo BASE.
|
||||
*/
|
||||
var v_Ps = Vector128.Create(s1 * n, 0, 0, 0);
|
||||
var v_S2 = Vector128.Create(s2, 0, 0, 0);
|
||||
var v_S1 = Vector128.Create(0u, 0, 0, 0);
|
||||
|
||||
do
|
||||
{
|
||||
/*
|
||||
* Load 32 input bytes.
|
||||
*/
|
||||
var bytes1 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
|
||||
BitConverter.ToUInt32(buf, bufPos + 4),
|
||||
BitConverter.ToUInt32(buf, bufPos + 8),
|
||||
BitConverter.ToUInt32(buf, bufPos + 12));
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
var bytes2 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
|
||||
BitConverter.ToUInt32(buf, bufPos + 4),
|
||||
BitConverter.ToUInt32(buf, bufPos + 8),
|
||||
BitConverter.ToUInt32(buf, bufPos + 12));
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
/*
|
||||
* Add previous block byte sum to v_ps.
|
||||
*/
|
||||
v_Ps = Sse2.Add(v_Ps, v_S1);
|
||||
/*
|
||||
* Horizontally add the bytes for s1, multiply-adds the
|
||||
* bytes by [ 32, 31, 30, ... ] for s2.
|
||||
*/
|
||||
v_S1 = Sse2.Add(v_S1, Sse2.SumAbsoluteDifferences(bytes1.AsByte(), zero).AsUInt32());
|
||||
|
||||
Vector128<short> mad1 =
|
||||
System.Runtime.Intrinsics.X86.Ssse3.MultiplyAddAdjacent(bytes1.AsByte(), tap1.AsSByte());
|
||||
|
||||
v_S2 = Sse2.Add(v_S2, Sse2.MultiplyAddAdjacent(mad1.AsInt16(), ones.AsInt16()).AsUInt32());
|
||||
v_S1 = Sse2.Add(v_S1, Sse2.SumAbsoluteDifferences(bytes2.AsByte(), zero).AsUInt32());
|
||||
|
||||
Vector128<short> mad2 =
|
||||
System.Runtime.Intrinsics.X86.Ssse3.MultiplyAddAdjacent(bytes2.AsByte(), tap2.AsSByte());
|
||||
|
||||
v_S2 = Sse2.Add(v_S2, Sse2.MultiplyAddAdjacent(mad2.AsInt16(), ones.AsInt16()).AsUInt32());
|
||||
} while(--n != 0);
|
||||
|
||||
v_S2 = Sse2.Add(v_S2, Sse2.ShiftLeftLogical(v_Ps, 5));
|
||||
/*
|
||||
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
|
||||
*/
|
||||
v_S1 = Sse2.Add(v_S1, Sse2.Shuffle(v_S1, 177));
|
||||
v_S1 = Sse2.Add(v_S1, Sse2.Shuffle(v_S1, 78));
|
||||
s1 += (uint)Sse2.ConvertToInt32(v_S1.AsInt32());
|
||||
v_S2 = Sse2.Add(v_S2, Sse2.Shuffle(v_S2, 177));
|
||||
v_S2 = Sse2.Add(v_S2, Sse2.Shuffle(v_S2, 78));
|
||||
s2 = (uint)Sse2.ConvertToInt32(v_S2.AsInt32());
|
||||
/*
|
||||
* Reduce.
|
||||
*/
|
||||
s1 %= Fletcher32Context.FLETCHER_MODULE;
|
||||
s2 %= Fletcher32Context.FLETCHER_MODULE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle leftover data.
|
||||
*/
|
||||
if(len != 0)
|
||||
{
|
||||
if(len >= 16)
|
||||
{
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
s2 += s1 += buf[bufPos++];
|
||||
len -= 16;
|
||||
}
|
||||
|
||||
while(len-- != 0)
|
||||
s2 += s1 += buf[bufPos++];
|
||||
|
||||
if(s1 >= Fletcher32Context.FLETCHER_MODULE)
|
||||
s1 -= Fletcher32Context.FLETCHER_MODULE;
|
||||
|
||||
s2 %= Fletcher32Context.FLETCHER_MODULE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the recombined sums.
|
||||
*/
|
||||
sum1 = (ushort)(s1 & 0xFFFF);
|
||||
sum2 = (ushort)(s2 & 0xFFFF);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
777
SabreTools.Hashing/Aaru.Checksums/FletcherContext.cs
Normal file
777
SabreTools.Hashing/Aaru.Checksums/FletcherContext.cs
Normal file
@@ -0,0 +1,777 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : FletcherContext.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Implements Fletcher-32 and Fletcher-16 algorithms.
|
||||
//
|
||||
// --[ 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
|
||||
// ****************************************************************************/
|
||||
|
||||
// Disabled because the speed is abnormally slow
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
#endif
|
||||
using System.Text;
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
using Aaru.Checksums.Fletcher32;
|
||||
#endif
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Helpers;
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
using Ssse3 = System.Runtime.Intrinsics.X86.Ssse3;
|
||||
#endif
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Implements the Fletcher-32 algorithm</summary>
|
||||
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
public sealed class Fletcher32Context : IChecksum
|
||||
{
|
||||
internal const ushort FLETCHER_MODULE = 0xFFFF;
|
||||
internal const uint NMAX = 5552;
|
||||
readonly IntPtr _nativeContext;
|
||||
readonly bool _useNative;
|
||||
ushort _sum1, _sum2;
|
||||
|
||||
/// <summary>Initializes the Fletcher-32 sums</summary>
|
||||
public Fletcher32Context()
|
||||
{
|
||||
_sum1 = 0xFFFF;
|
||||
_sum2 = 0xFFFF;
|
||||
|
||||
if(!Native.IsSupported)
|
||||
return;
|
||||
|
||||
_nativeContext = fletcher32_init();
|
||||
_useNative = _nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Fletcher-32";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("0E51B39F-C5E6-4CED-9E59-BA5A42B3B2F4");
|
||||
|
||||
/// <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 _sum1, ref _sum2, data, len, _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()
|
||||
{
|
||||
var finalSum = (uint)(_sum2 << 16 | _sum1);
|
||||
|
||||
if(!_useNative)
|
||||
return BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
fletcher32_final(_nativeContext, ref finalSum);
|
||||
fletcher32_free(_nativeContext);
|
||||
|
||||
return BigEndianBitConverter.GetBytes(finalSum);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
var finalSum = (uint)(_sum2 << 16 | _sum1);
|
||||
|
||||
if(_useNative)
|
||||
{
|
||||
fletcher32_final(_nativeContext, ref finalSum);
|
||||
fletcher32_free(_nativeContext);
|
||||
}
|
||||
|
||||
var fletcherOutput = new StringBuilder();
|
||||
|
||||
for(var i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
|
||||
fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
|
||||
|
||||
return fletcherOutput.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern IntPtr fletcher32_init();
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern int fletcher32_update(IntPtr ctx, byte[] data, uint len);
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern int fletcher32_final(IntPtr ctx, ref uint crc);
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern void fletcher32_free(IntPtr ctx);
|
||||
|
||||
static void Step(ref ushort previousSum1, ref ushort previousSum2, byte[] data, uint len, bool useNative,
|
||||
IntPtr nativeContext)
|
||||
{
|
||||
if(useNative)
|
||||
{
|
||||
fletcher32_update(nativeContext, data, len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
if(Ssse3.IsSupported)
|
||||
{
|
||||
Fletcher32.Ssse3.Step(ref previousSum1, ref previousSum2, data, len);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
if(AdvSimd.IsSupported)
|
||||
{
|
||||
Neon.Step(ref previousSum1, ref previousSum2, data, len);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint sum1 = previousSum1;
|
||||
uint sum2 = previousSum2;
|
||||
var dataOff = 0;
|
||||
|
||||
switch(len)
|
||||
{
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
case 1:
|
||||
{
|
||||
sum1 += data[dataOff];
|
||||
|
||||
if(sum1 >= FLETCHER_MODULE)
|
||||
sum1 -= FLETCHER_MODULE;
|
||||
|
||||
sum2 += sum1;
|
||||
|
||||
if(sum2 >= FLETCHER_MODULE)
|
||||
sum2 -= FLETCHER_MODULE;
|
||||
|
||||
previousSum1 = (ushort)(sum1 & 0xFFFF);
|
||||
previousSum2 = (ushort)(sum2 & 0xFFFF);
|
||||
|
||||
return;
|
||||
}
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
case < 16:
|
||||
{
|
||||
while(len-- > 0)
|
||||
{
|
||||
sum1 += data[dataOff++];
|
||||
sum2 += sum1;
|
||||
}
|
||||
|
||||
if(sum1 >= FLETCHER_MODULE)
|
||||
sum1 -= FLETCHER_MODULE;
|
||||
|
||||
sum2 %= FLETCHER_MODULE; /* only added so many FLETCHER_MODULE's */
|
||||
previousSum1 = (ushort)(sum1 & 0xFFFF);
|
||||
previousSum2 = (ushort)(sum2 & 0xFFFF);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while(len >= NMAX)
|
||||
{
|
||||
len -= NMAX;
|
||||
uint n = NMAX / 16;
|
||||
|
||||
do
|
||||
{
|
||||
sum1 += data[dataOff];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
|
||||
/* 16 sums unrolled */
|
||||
dataOff += 16;
|
||||
} while(--n != 0);
|
||||
|
||||
sum1 %= FLETCHER_MODULE;
|
||||
sum2 %= FLETCHER_MODULE;
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if(len != 0)
|
||||
{
|
||||
/* avoid modulos if none remaining */
|
||||
while(len >= 16)
|
||||
{
|
||||
len -= 16;
|
||||
sum1 += data[dataOff];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
|
||||
dataOff += 16;
|
||||
}
|
||||
|
||||
while(len-- != 0)
|
||||
{
|
||||
sum1 += data[dataOff++];
|
||||
sum2 += sum1;
|
||||
}
|
||||
|
||||
sum1 %= FLETCHER_MODULE;
|
||||
sum2 %= FLETCHER_MODULE;
|
||||
}
|
||||
|
||||
previousSum1 = (ushort)(sum1 & 0xFFFF);
|
||||
previousSum2 = (ushort)(sum2 & 0xFFFF);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
nativeContext = fletcher32_init();
|
||||
|
||||
if(nativeContext == IntPtr.Zero)
|
||||
useNative = false;
|
||||
}
|
||||
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
|
||||
ushort localSum1 = 0xFFFF;
|
||||
ushort localSum2 = 0xFFFF;
|
||||
|
||||
var buffer = new byte[65536];
|
||||
int read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
|
||||
while(read > 0)
|
||||
{
|
||||
Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
|
||||
|
||||
read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
}
|
||||
|
||||
var finalSum = (uint)(localSum2 << 16 | localSum1);
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
fletcher32_final(nativeContext, ref finalSum);
|
||||
fletcher32_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
var fletcherOutput = new StringBuilder();
|
||||
|
||||
foreach(byte h in hash)
|
||||
fletcherOutput.Append(h.ToString("x2"));
|
||||
|
||||
fileStream.Close();
|
||||
|
||||
return fletcherOutput.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)
|
||||
{
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
nativeContext = fletcher32_init();
|
||||
|
||||
if(nativeContext == IntPtr.Zero)
|
||||
useNative = false;
|
||||
}
|
||||
|
||||
ushort localSum1 = 0xFFFF;
|
||||
ushort localSum2 = 0xFFFF;
|
||||
|
||||
Step(ref localSum1, ref localSum2, data, len, useNative, nativeContext);
|
||||
|
||||
var finalSum = (uint)(localSum2 << 16 | localSum1);
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
fletcher32_final(nativeContext, ref finalSum);
|
||||
fletcher32_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
var adlerOutput = new StringBuilder();
|
||||
|
||||
foreach(byte h in hash)
|
||||
adlerOutput.Append(h.ToString("x2"));
|
||||
|
||||
return adlerOutput.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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Implements the Fletcher-16 algorithm</summary>
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||
public sealed class Fletcher16Context : IChecksum
|
||||
{
|
||||
const byte FLETCHER_MODULE = 0xFF;
|
||||
const byte NMAX = 22;
|
||||
|
||||
readonly IntPtr _nativeContext;
|
||||
readonly bool _useNative;
|
||||
byte _sum1, _sum2;
|
||||
|
||||
/// <summary>Initializes the Fletcher-16 sums</summary>
|
||||
public Fletcher16Context()
|
||||
{
|
||||
_sum1 = 0xFF;
|
||||
_sum2 = 0xFF;
|
||||
|
||||
if(!Native.IsSupported)
|
||||
return;
|
||||
|
||||
_nativeContext = fletcher16_init();
|
||||
_useNative = _nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Fletcher-16";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("80C51F1D-71F8-4741-A0CF-18FA8102EE4B");
|
||||
|
||||
/// <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 _sum1, ref _sum2, data, len, _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()
|
||||
{
|
||||
var finalSum = (ushort)(_sum2 << 8 | _sum1);
|
||||
|
||||
if(!_useNative)
|
||||
return BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
fletcher16_final(_nativeContext, ref finalSum);
|
||||
fletcher16_free(_nativeContext);
|
||||
|
||||
return BigEndianBitConverter.GetBytes(finalSum);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
var finalSum = (ushort)(_sum2 << 8 | _sum1);
|
||||
|
||||
if(_useNative)
|
||||
{
|
||||
fletcher16_final(_nativeContext, ref finalSum);
|
||||
fletcher16_free(_nativeContext);
|
||||
}
|
||||
|
||||
var fletcherOutput = new StringBuilder();
|
||||
|
||||
for(var i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
|
||||
fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
|
||||
|
||||
return fletcherOutput.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern IntPtr fletcher16_init();
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern int fletcher16_update(IntPtr ctx, byte[] data, uint len);
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern int fletcher16_final(IntPtr ctx, ref ushort checksum);
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern void fletcher16_free(IntPtr ctx);
|
||||
|
||||
static void Step(ref byte previousSum1, ref byte previousSum2, byte[] data, uint len, bool useNative,
|
||||
IntPtr nativeContext)
|
||||
{
|
||||
if(useNative)
|
||||
{
|
||||
fletcher16_update(nativeContext, data, len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint sum1 = previousSum1;
|
||||
uint sum2 = previousSum2;
|
||||
var dataOff = 0;
|
||||
|
||||
switch(len)
|
||||
{
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
case 1:
|
||||
{
|
||||
sum1 += data[dataOff];
|
||||
|
||||
if(sum1 >= FLETCHER_MODULE)
|
||||
sum1 -= FLETCHER_MODULE;
|
||||
|
||||
sum2 += sum1;
|
||||
|
||||
if(sum2 >= FLETCHER_MODULE)
|
||||
sum2 -= FLETCHER_MODULE;
|
||||
|
||||
previousSum1 = (byte)(sum1 & 0xFF);
|
||||
previousSum2 = (byte)(sum2 & 0xFF);
|
||||
|
||||
return;
|
||||
}
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
case < 11:
|
||||
{
|
||||
while(len-- > 0)
|
||||
{
|
||||
sum1 += data[dataOff++];
|
||||
sum2 += sum1;
|
||||
}
|
||||
|
||||
if(sum1 >= FLETCHER_MODULE)
|
||||
sum1 -= FLETCHER_MODULE;
|
||||
|
||||
sum2 %= FLETCHER_MODULE; /* only added so many FLETCHER_MODULE's */
|
||||
previousSum1 = (byte)(sum1 & 0xFF);
|
||||
previousSum2 = (byte)(sum2 & 0xFF);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while(len >= NMAX)
|
||||
{
|
||||
len -= NMAX;
|
||||
uint n = NMAX / 11;
|
||||
|
||||
do
|
||||
{
|
||||
sum1 += data[dataOff];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2];
|
||||
sum2 += sum1;
|
||||
|
||||
/* 11 sums unrolled */
|
||||
dataOff += 11;
|
||||
} while(--n != 0);
|
||||
|
||||
sum1 %= FLETCHER_MODULE;
|
||||
sum2 %= FLETCHER_MODULE;
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if(len != 0)
|
||||
{
|
||||
/* avoid modulos if none remaining */
|
||||
while(len >= 11)
|
||||
{
|
||||
len -= 11;
|
||||
sum1 += data[dataOff];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += data[dataOff + 8 + 2];
|
||||
sum2 += sum1;
|
||||
|
||||
dataOff += 11;
|
||||
}
|
||||
|
||||
while(len-- != 0)
|
||||
{
|
||||
sum1 += data[dataOff++];
|
||||
sum2 += sum1;
|
||||
}
|
||||
|
||||
sum1 %= FLETCHER_MODULE;
|
||||
sum2 %= FLETCHER_MODULE;
|
||||
}
|
||||
|
||||
previousSum1 = (byte)(sum1 & 0xFF);
|
||||
previousSum2 = (byte)(sum2 & 0xFF);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
nativeContext = fletcher16_init();
|
||||
|
||||
if(nativeContext == IntPtr.Zero)
|
||||
useNative = false;
|
||||
}
|
||||
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
|
||||
byte localSum1 = 0xFF;
|
||||
byte localSum2 = 0xFF;
|
||||
|
||||
var buffer = new byte[65536];
|
||||
int read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
|
||||
while(read > 0)
|
||||
{
|
||||
Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
|
||||
|
||||
read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
}
|
||||
|
||||
var finalSum = (ushort)(localSum2 << 8 | localSum1);
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
fletcher16_final(nativeContext, ref finalSum);
|
||||
fletcher16_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
var fletcherOutput = new StringBuilder();
|
||||
|
||||
foreach(byte h in hash)
|
||||
fletcherOutput.Append(h.ToString("x2"));
|
||||
|
||||
fileStream.Close();
|
||||
|
||||
return fletcherOutput.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)
|
||||
{
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
nativeContext = fletcher16_init();
|
||||
|
||||
if(nativeContext == IntPtr.Zero)
|
||||
useNative = false;
|
||||
}
|
||||
|
||||
byte localSum1 = 0xFF;
|
||||
byte localSum2 = 0xFF;
|
||||
|
||||
Step(ref localSum1, ref localSum2, data, len, useNative, nativeContext);
|
||||
|
||||
var finalSum = (ushort)(localSum2 << 8 | localSum1);
|
||||
|
||||
if(useNative)
|
||||
{
|
||||
fletcher16_final(nativeContext, ref finalSum);
|
||||
fletcher16_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(finalSum);
|
||||
|
||||
var adlerOutput = new StringBuilder();
|
||||
|
||||
foreach(byte h in hash)
|
||||
adlerOutput.Append(h.ToString("x2"));
|
||||
|
||||
return adlerOutput.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);
|
||||
}
|
||||
83
SabreTools.Hashing/Aaru.Checksums/Native.cs
Normal file
83
SabreTools.Hashing/Aaru.Checksums/Native.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : Native.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Checks that Aaru.Checksums.Native library is available and usable.
|
||||
//
|
||||
// --[ 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.Runtime.InteropServices;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
|
||||
/// <summary>Handles native implementations of compression algorithms</summary>
|
||||
public static class Native
|
||||
{
|
||||
static bool _checked;
|
||||
static bool _supported;
|
||||
|
||||
/// <summary>Set to return native as never supported</summary>
|
||||
public static bool ForceManaged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If set to <c>true</c> the native library was found and loaded correctly and its reported version is
|
||||
/// compatible.
|
||||
/// </summary>
|
||||
public static bool IsSupported
|
||||
{
|
||||
get
|
||||
{
|
||||
if(ForceManaged)
|
||||
return false;
|
||||
|
||||
if(_checked)
|
||||
return _supported;
|
||||
|
||||
ulong version;
|
||||
_checked = true;
|
||||
|
||||
try
|
||||
{
|
||||
version = get_acn_version();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_supported = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Check version compatibility
|
||||
_supported = version >= 0x06000000;
|
||||
|
||||
return _supported;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
static extern ulong get_acn_version();
|
||||
}
|
||||
324
SabreTools.Hashing/Aaru.Helpers/BigEndianBitConverter.cs
Normal file
324
SabreTools.Hashing/Aaru.Helpers/BigEndianBitConverter.cs
Normal file
@@ -0,0 +1,324 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : BigEndianBitConverter.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Helpers.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Override of System.BitConverter that knows how to handle big-endian.
|
||||
//
|
||||
// --[ 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.Linq;
|
||||
|
||||
namespace Aaru.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts base data types to an array of bytes, and an array of bytes to base data types. All info taken from
|
||||
/// the meta data of System.BitConverter. This implementation allows for Endianness consideration.
|
||||
/// </summary>
|
||||
public static class BigEndianBitConverter
|
||||
{
|
||||
/// <summary>Converts the specified double-precision floating point number to a 64-bit signed integer.</summary>
|
||||
/// <param name="value">The number to convert.</param>
|
||||
/// <returns>A 64-bit signed integer whose value is equivalent to value.</returns>
|
||||
/// <exception cref="NotImplementedException">It is not currently implemented</exception>
|
||||
public static long DoubleToInt64Bits(double value) => throw new NotImplementedException();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <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();
|
||||
|
||||
/// <summary>Converts the specified 64-bit signed integer to a double-precision floating point number.</summary>
|
||||
/// <param name="value">The number to convert.</param>
|
||||
/// <returns>A double-precision floating point number whose value is equivalent to value.</returns>
|
||||
public static double Int64BitsToDouble(long value) => throw new NotImplementedException();
|
||||
|
||||
/// <summary>Returns a Boolean value converted from one byte at a specified position in a byte array.</summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>true if the byte at <see cref="startIndex" /> in value is nonzero; otherwise, false.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// <see cref="startIndex" /> is less than zero or greater than the
|
||||
/// length of value minus 1.
|
||||
/// </exception>
|
||||
public static bool ToBoolean(byte[] value, int startIndex) => throw new NotImplementedException();
|
||||
|
||||
/// <summary>Returns a Unicode character converted from two bytes at a specified position in a byte array.</summary>
|
||||
/// <param name="value">An array.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A character formed by two bytes beginning at <see cref="startIndex" />.</returns>
|
||||
/// <exception cref="System.ArgumentException"><see cref="startIndex" /> equals the length of value minus 1.</exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// <see cref="startIndex" /> is less than zero or greater than the
|
||||
/// length of value minus 1.
|
||||
/// </exception>
|
||||
public static char ToChar(byte[] value, int startIndex) => throw new NotImplementedException();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a double-precision floating point number converted from eight bytes at a specified position in a byte
|
||||
/// array.
|
||||
/// </summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A double precision floating point number formed by eight bytes beginning at <see cref="startIndex" />.</returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// <see cref="startIndex" /> is greater than or equal to the length of value
|
||||
/// minus 7, and is less than or equal to the length of value minus 1.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// <see cref="startIndex" /> is less than zero or greater than the
|
||||
/// length of value minus 1.
|
||||
/// </exception>
|
||||
public static double ToDouble(byte[] value, int startIndex) => throw new NotImplementedException();
|
||||
|
||||
/// <summary>Returns a 16-bit signed integer converted from two bytes at a specified position in a byte array.</summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A 16-bit signed integer formed by two bytes beginning at <see cref="startIndex" />.</returns>
|
||||
/// <exception cref="System.ArgumentException"><see cref="startIndex" /> equals the length of value minus 1.</exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// startIndex is less than zero or greater than the length of value
|
||||
/// minus 1.
|
||||
/// </exception>
|
||||
public static short ToInt16(byte[] value, int startIndex) =>
|
||||
BitConverter.ToInt16(value.Reverse().ToArray(), 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>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A 32-bit signed integer formed by four bytes beginning at <see cref="startIndex" />.</returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// <see cref="startIndex" /> is greater than or equal to the length of value
|
||||
/// minus 3, and is less than or equal to the length of value minus 1.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// startIndex is less than zero or greater than the length of value
|
||||
/// minus 1.
|
||||
/// </exception>
|
||||
public static int ToInt32(byte[] value, int startIndex) =>
|
||||
BitConverter.ToInt32(value.Reverse().ToArray(), 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>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A 64-bit signed integer formed by eight bytes beginning at <see cref="startIndex" />.</returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// <see cref="startIndex" /> is greater than or equal to the length of value
|
||||
/// minus 7, and is less than or equal to the length of value minus 1.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// <see cref="startIndex" /> is less than zero or greater than the
|
||||
/// length of value minus 1.
|
||||
/// </exception>
|
||||
public static long ToInt64(byte[] value, int startIndex) =>
|
||||
BitConverter.ToInt64(value.Reverse().ToArray(), value.Length - sizeof(long) - startIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a single-precision floating point number converted from four bytes at a specified position in a byte
|
||||
/// array.
|
||||
/// </summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A single-precision floating point number formed by four bytes beginning at <see cref="startIndex" />.</returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// <see cref="startIndex" /> is greater than or equal to the length of value
|
||||
/// minus 3, and is less than or equal to the length of value minus 1.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// <see cref="startIndex" /> is less than zero or greater than the
|
||||
/// length of value minus 1.
|
||||
/// </exception>
|
||||
public static float ToSingle(byte[] value, int startIndex) =>
|
||||
BitConverter.ToSingle(value.Reverse().ToArray(), value.Length - sizeof(float) - startIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the numeric value of each element of a specified array of bytes to its equivalent hexadecimal string
|
||||
/// representation.
|
||||
/// </summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <returns>
|
||||
/// A System.String of hexadecimal pairs separated by hyphens, where each pair represents the corresponding
|
||||
/// 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());
|
||||
|
||||
/// <summary>
|
||||
/// Converts the numeric value of each element of a specified subarray of bytes to its equivalent hexadecimal
|
||||
/// string representation.
|
||||
/// </summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>
|
||||
/// A System.String of hexadecimal pairs separated by hyphens, where each pair represents the corresponding
|
||||
/// element in a subarray of value; for example, "7F-2C-4A".
|
||||
/// </returns>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// startIndex is less than zero or greater than the length of value
|
||||
/// minus 1.
|
||||
/// </exception>
|
||||
public static string ToString(byte[] value, int startIndex) =>
|
||||
BitConverter.ToString(value.Reverse().ToArray(), startIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the numeric value of each element of a specified subarray of bytes to its equivalent hexadecimal
|
||||
/// string representation.
|
||||
/// </summary>
|
||||
/// <param name="value">An array of bytes.</param>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <param name="length">The number of array elements in value to convert.</param>
|
||||
/// <returns>
|
||||
/// A System.String of hexadecimal pairs separated by hyphens, where each pair represents the corresponding
|
||||
/// element in a subarray of value; for example, "7F-2C-4A".
|
||||
/// </returns>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// startIndex or length is less than zero. -or- startIndex is greater
|
||||
/// than zero and is greater than or equal to the length of value.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// The combination of startIndex and length does not specify a position within
|
||||
/// 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);
|
||||
|
||||
/// <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>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A 16-bit unsigned integer formed by two bytes beginning at startIndex.</returns>
|
||||
/// <exception cref="System.ArgumentException">startIndex equals the length of value minus 1.</exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// startIndex is less than zero or greater than the length of value
|
||||
/// minus 1.
|
||||
/// </exception>
|
||||
public static ushort ToUInt16(byte[] value, int startIndex) =>
|
||||
BitConverter.ToUInt16(value.Reverse().ToArray(), 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>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A 32-bit unsigned integer formed by four bytes beginning at startIndex.</returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// startIndex is greater than or equal to the length of value minus 3, and is
|
||||
/// less than or equal to the length of value minus 1.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// startIndex is less than zero or greater than the length of value
|
||||
/// minus 1.
|
||||
/// </exception>
|
||||
public static uint ToUInt32(byte[] value, int startIndex) =>
|
||||
BitConverter.ToUInt32(value.Reverse().ToArray(), 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>
|
||||
/// <param name="startIndex">The starting position within value.</param>
|
||||
/// <returns>A 64-bit unsigned integer formed by the eight bytes beginning at startIndex.</returns>
|
||||
/// <exception cref="System.ArgumentException">
|
||||
/// startIndex is greater than or equal to the length of value minus 7, and is
|
||||
/// less than or equal to the length of value minus 1.
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">value is null.</exception>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">
|
||||
/// startIndex is less than zero or greater than the length of value
|
||||
/// minus 1.
|
||||
/// </exception>
|
||||
public static ulong ToUInt64(byte[] value, int startIndex) =>
|
||||
BitConverter.ToUInt64(value.Reverse().ToArray(), 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>
|
||||
/// <param name="startIndex">Start of the byte array to process</param>
|
||||
/// <returns>Processed Guid</returns>
|
||||
public static Guid ToGuid(byte[] value, int startIndex) => new Guid(ToUInt32(value, 0 + startIndex),
|
||||
ToUInt16(value, 4 + startIndex),
|
||||
ToUInt16(value, 6 + startIndex),
|
||||
value[8 + startIndex + 0],
|
||||
value[8 + startIndex + 1],
|
||||
value[8 + startIndex + 2],
|
||||
value[8 + startIndex + 3],
|
||||
value[8 + startIndex + 5],
|
||||
value[8 + startIndex + 5],
|
||||
value[8 + startIndex + 6],
|
||||
value[8 + startIndex + 7]);
|
||||
}
|
||||
}
|
||||
72
SabreTools.Hashing/Aaru.Helpers/Extensions.cs
Normal file
72
SabreTools.Hashing/Aaru.Helpers/Extensions.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : Extensions.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Helpers.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Provides class extensions.
|
||||
//
|
||||
// --[ 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.IO;
|
||||
|
||||
namespace Aaru.Helpers;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the
|
||||
/// position within the stream by the number of bytes read.<br /> Guarantees the whole count of bytes is read or EOF is
|
||||
/// found
|
||||
/// </summary>
|
||||
/// <param name="s">Stream to extend</param>
|
||||
/// <param name="buffer">
|
||||
/// An array of bytes. When this method returns, the buffer contains the specified byte array with the
|
||||
/// values between <see cref="offset" /> and (<see cref="offset" /> + <see cref="count" /> - 1) replaced by the bytes
|
||||
/// read from the current source.
|
||||
/// </param>
|
||||
/// <param name="offset">
|
||||
/// The zero-based byte offset in <see cref="buffer" /> at which to begin storing the data read from
|
||||
/// the current stream.
|
||||
/// </param>
|
||||
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||
/// <returns>
|
||||
/// 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)
|
||||
{
|
||||
var pos = 0;
|
||||
int read;
|
||||
|
||||
do
|
||||
{
|
||||
read = s.Read(buffer, pos + offset, count - pos);
|
||||
pos += read;
|
||||
} while(read > 0);
|
||||
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
68
SabreTools.Hashing/CRC32/NaiveCRC.cs
Normal file
68
SabreTools.Hashing/CRC32/NaiveCRC.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,34 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2012-2015 Eugene Larchenko (spct@mail.ru)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
* 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 OptimizedCRC
|
||||
namespace CRC32
|
||||
{
|
||||
internal class OptimizedCRC : IDisposable
|
||||
public class OptimizedCRC
|
||||
{
|
||||
private const uint kCrcPoly = 0xEDB88320;
|
||||
private const uint kInitial = 0xFFFFFFFF;
|
||||
private const int CRC_NUM_TABLES = 8;
|
||||
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 * CRC_NUM_TABLES];
|
||||
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) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
}
|
||||
r = (r >> 1) ^ (kPoly & ~((r & 1) - 1));
|
||||
Table[i] = r;
|
||||
}
|
||||
for (; i < 256 * CRC_NUM_TABLES; i++)
|
||||
for (; i < 256 * NUM_TABLES; i++)
|
||||
{
|
||||
uint r = Table[i - 256];
|
||||
Table[i] = Table[r & 0xFF] ^ (r >> 8);
|
||||
@@ -56,49 +36,37 @@ namespace OptimizedCRC
|
||||
}
|
||||
}
|
||||
|
||||
public uint UnsignedValue;
|
||||
private uint value;
|
||||
|
||||
public OptimizedCRC()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset CRC
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
UnsignedValue = kInitial;
|
||||
value = kInit;
|
||||
}
|
||||
|
||||
public int Value
|
||||
{
|
||||
get { return (int)~UnsignedValue; }
|
||||
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;
|
||||
}
|
||||
new ArraySegment<byte>(data, offset, count); // check arguments
|
||||
if (count <= 0) return;
|
||||
|
||||
var table = OptimizedCRC.Table;
|
||||
|
||||
uint crc = UnsignedValue;
|
||||
uint crc = value;
|
||||
|
||||
for (; (offset & 7) != 0 && count != 0; count--)
|
||||
{
|
||||
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
|
||||
}
|
||||
|
||||
if (count >= 8)
|
||||
{
|
||||
/*
|
||||
* Idea from 7-zip project sources (http://7-zip.org/sdk.html)
|
||||
*/
|
||||
|
||||
int end = (count - 8) & ~7;
|
||||
count -= end;
|
||||
end += offset;
|
||||
@@ -121,11 +89,9 @@ namespace OptimizedCRC
|
||||
}
|
||||
|
||||
while (count-- != 0)
|
||||
{
|
||||
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
|
||||
}
|
||||
|
||||
UnsignedValue = crc;
|
||||
value = crc;
|
||||
}
|
||||
|
||||
static public int Compute(byte[] data, int offset, int count)
|
||||
@@ -140,14 +106,5 @@ namespace OptimizedCRC
|
||||
return Compute(data, 0, data.Length);
|
||||
}
|
||||
|
||||
static public int Compute(ArraySegment<byte> block)
|
||||
{
|
||||
return Compute(block.Array!, block.Offset, block.Count);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
UnsignedValue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
302
SabreTools.Hashing/CRC32/ParallelCRC.cs
Normal file
302
SabreTools.Hashing/CRC32/ParallelCRC.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
76
SabreTools.Hashing/Constants.cs
Normal file
76
SabreTools.Hashing/Constants.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
namespace SabreTools.Hashing
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
#region 0-byte file constants
|
||||
|
||||
public const long SizeZero = 0;
|
||||
public const string CRCZero = "00000000";
|
||||
public static readonly byte[] CRCZeroBytes = [0x00, 0x00, 0x00, 0x00];
|
||||
public const string MD5Zero = "d41d8cd98f00b204e9800998ecf8427e";
|
||||
public static readonly byte[] MD5ZeroBytes = [ 0xd4, 0x1d, 0x8c, 0xd9,
|
||||
0x8f, 0x00, 0xb2, 0x04,
|
||||
0xe9, 0x80, 0x09, 0x98,
|
||||
0xec, 0xf8, 0x42, 0x7e ];
|
||||
public const string SHA1Zero = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
|
||||
public static readonly byte[] SHA1ZeroBytes = [ 0xda, 0x39, 0xa3, 0xee,
|
||||
0x5e, 0x6b, 0x4b, 0x0d,
|
||||
0x32, 0x55, 0xbf, 0xef,
|
||||
0x95, 0x60, 0x18, 0x90,
|
||||
0xaf, 0xd8, 0x07, 0x09 ];
|
||||
public const string SHA256Zero = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
|
||||
public static readonly byte[] SHA256ZeroBytes = [ 0xba, 0x78, 0x16, 0xbf,
|
||||
0x8f, 0x01, 0xcf, 0xea,
|
||||
0x41, 0x41, 0x40, 0xde,
|
||||
0x5d, 0xae, 0x22, 0x23,
|
||||
0xb0, 0x03, 0x61, 0xa3,
|
||||
0x96, 0x17, 0x7a, 0x9c,
|
||||
0xb4, 0x10, 0xff, 0x61,
|
||||
0xf2, 0x00, 0x15, 0xad ];
|
||||
public const string SHA384Zero = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
|
||||
public static readonly byte[] SHA384ZeroBytes = [ 0xcb, 0x00, 0x75, 0x3f,
|
||||
0x45, 0xa3, 0x5e, 0x8b,
|
||||
0xb5, 0xa0, 0x3d, 0x69,
|
||||
0x9a, 0xc6, 0x50, 0x07,
|
||||
0x27, 0x2c, 0x32, 0xab,
|
||||
0x0e, 0xde, 0xd1, 0x63,
|
||||
0x1a, 0x8b, 0x60, 0x5a,
|
||||
0x43, 0xff, 0x5b, 0xed,
|
||||
0x80, 0x86, 0x07, 0x2b,
|
||||
0xa1, 0xe7, 0xcc, 0x23,
|
||||
0x58, 0xba, 0xec, 0xa1,
|
||||
0x34, 0xc8, 0x25, 0xa7 ];
|
||||
public const string SHA512Zero = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
|
||||
public static readonly byte[] SHA512ZeroBytes = [ 0xdd, 0xaf, 0x35, 0xa1,
|
||||
0x93, 0x61, 0x7a, 0xba,
|
||||
0xcc, 0x41, 0x73, 0x49,
|
||||
0xae, 0x20, 0x41, 0x31,
|
||||
0x12, 0xe6, 0xfa, 0x4e,
|
||||
0x89, 0xa9, 0x7e, 0xa2,
|
||||
0x0a, 0x9e, 0xee, 0xe6,
|
||||
0x4b, 0x55, 0xd3, 0x9a,
|
||||
0x21, 0x92, 0x99, 0x2a,
|
||||
0x27, 0x4f, 0xc1, 0xa8,
|
||||
0x36, 0xba, 0x3c, 0x23,
|
||||
0xa3, 0xfe, 0xeb, 0xbd,
|
||||
0x45, 0x4d, 0x44, 0x23,
|
||||
0x64, 0x3c, 0xe8, 0x0e,
|
||||
0x2a, 0x9a, 0xc9, 0x4f,
|
||||
0xa5, 0x4c, 0xa4, 0x9f ];
|
||||
public const string SpamSumZero = "QXX";
|
||||
public static readonly byte[] SpamSumZeroBytes = [0x51, 0x58, 0x58];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Hash string length constants
|
||||
|
||||
public const int CRCLength = 8;
|
||||
public const int MD5Length = 32;
|
||||
public const int SHA1Length = 40;
|
||||
public const int SHA256Length = 64;
|
||||
public const int SHA384Length = 96;
|
||||
public const int SHA512Length = 128;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using Compress.ThreadReaders;
|
||||
|
||||
namespace SabreTools.Hashing
|
||||
{
|
||||
@@ -46,18 +45,38 @@ namespace SabreTools.Hashing
|
||||
public static Dictionary<HashType, string?>? GetFileHashes(string filename)
|
||||
=> GetFileHashesAndSize(filename, out _);
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes from an input file path
|
||||
/// </summary>
|
||||
/// <param name="filename">Path to the input file</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
public static Dictionary<HashType, byte[]?>? GetFileHashArrays(string filename)
|
||||
=> GetFileHashArraysAndSize(filename, out _);
|
||||
|
||||
/// <summary>
|
||||
/// Get a hash from an input file path
|
||||
/// </summary>
|
||||
/// <param name="filename">Path to the input file</param>
|
||||
/// <param name="hashType">Hash type to get from the file</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
/// <returns>Hash on success, null on error</returns>
|
||||
public static string? GetFileHash(string filename, HashType hashType)
|
||||
{
|
||||
var hashes = GetFileHashes(filename, [hashType]);
|
||||
return hashes?[hashType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a hash from an input file path
|
||||
/// </summary>
|
||||
/// <param name="filename">Path to the input file</param>
|
||||
/// <param name="hashType">Hash type to get from the file</param>
|
||||
/// <returns>Hash on success, null on error</returns>
|
||||
public static byte[]? GetFileHashArray(string filename, HashType hashType)
|
||||
{
|
||||
var hashes = GetFileHashArrays(filename, [hashType]);
|
||||
return hashes?[hashType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes from an input file path
|
||||
/// </summary>
|
||||
@@ -67,6 +86,15 @@ namespace SabreTools.Hashing
|
||||
public static Dictionary<HashType, string?>? GetFileHashes(string filename, HashType[] hashTypes)
|
||||
=> GetFileHashesAndSize(filename, hashTypes, out _);
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes from an input file path
|
||||
/// </summary>
|
||||
/// <param name="filename">Path to the input file</param>
|
||||
/// <param name="hashTypes">Array of hash types to get from the file</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
public static Dictionary<HashType, byte[]?>? GetFileHashArrays(string filename, HashType[] hashTypes)
|
||||
=> GetFileHashArraysAndSize(filename, hashTypes, out _);
|
||||
|
||||
#endregion
|
||||
|
||||
#region File Hashes With Size
|
||||
@@ -85,18 +113,44 @@ namespace SabreTools.Hashing
|
||||
return GetFileHashesAndSize(filename, hashTypes, out size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes and size from an input file path
|
||||
/// </summary>
|
||||
/// <param name="filename">Path to the input file</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
public static Dictionary<HashType, byte[]?>? GetFileHashArraysAndSize(string filename, out long size)
|
||||
{
|
||||
// Create a hash array for all entries
|
||||
HashType[] hashTypes = (HashType[])Enum.GetValues(typeof(HashType));
|
||||
|
||||
// Return the hashes from the stream
|
||||
return GetFileHashArraysAndSize(filename, hashTypes, out size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a hash and size from an input file path
|
||||
/// </summary>
|
||||
/// <param name="filename">Path to the input file</param>
|
||||
/// <param name="hashType">Hash type to get from the file</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
/// <returns>Hash and size on success, null on error</returns>
|
||||
public static string? GetFileHashAndSize(string filename, HashType hashType, out long size)
|
||||
{
|
||||
var hashes = GetFileHashesAndSize(filename, [hashType], out size);
|
||||
return hashes?[hashType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a hash and size from an input file path
|
||||
/// </summary>
|
||||
/// <param name="filename">Path to the input file</param>
|
||||
/// <param name="hashType">Hash type to get from the file</param>
|
||||
/// <returns>Hash and size on success, null on error</returns>
|
||||
public static byte[]? GetFileHashArrayAndSize(string filename, HashType hashType, out long size)
|
||||
{
|
||||
var hashes = GetFileHashArraysAndSize(filename, [hashType], out size);
|
||||
return hashes?[hashType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes and size from an input file path
|
||||
/// </summary>
|
||||
@@ -122,6 +176,31 @@ namespace SabreTools.Hashing
|
||||
return GetStreamHashes(input, hashTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes and size from an input file path
|
||||
/// </summary>
|
||||
/// <param name="filename">Path to the input file</param>
|
||||
/// <param name="hashTypes">Array of hash types to get from the file</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
public static Dictionary<HashType, byte[]?>? GetFileHashArraysAndSize(string filename, HashType[] hashTypes, out long size)
|
||||
{
|
||||
// If the file doesn't exist, we can't do anything
|
||||
if (!File.Exists(filename))
|
||||
{
|
||||
size = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set the file size
|
||||
size = new FileInfo(filename).Length;
|
||||
|
||||
// Open the input file
|
||||
var input = File.OpenRead(filename);
|
||||
|
||||
// Return the hashes from the stream
|
||||
return GetStreamHashArrays(input, hashTypes);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Byte Array Hashes
|
||||
@@ -140,18 +219,44 @@ namespace SabreTools.Hashing
|
||||
return GetStreamHashes(new MemoryStream(input), hashTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes from an input byte array
|
||||
/// </summary>
|
||||
/// <param name="input">Byte array to hash</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
public static Dictionary<HashType, byte[]?>? GetByteArrayHashArrays(byte[] input)
|
||||
{
|
||||
// Create a hash array for all entries
|
||||
HashType[] hashTypes = (HashType[])Enum.GetValues(typeof(HashType));
|
||||
|
||||
// Return the hashes from the stream
|
||||
return GetStreamHashArrays(new MemoryStream(input), hashTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a hash from an input byte array
|
||||
/// </summary>
|
||||
/// <param name="input">Byte array to hash</param>
|
||||
/// <param name="hashType">Hash type to get from the file</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
/// <returns>Hash on success, null on error</returns>
|
||||
public static string? GetByteArrayHash(byte[] input, HashType hashType)
|
||||
{
|
||||
var hashes = GetStreamHashes(new MemoryStream(input), [hashType]);
|
||||
return hashes?[hashType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a hash from an input byte array
|
||||
/// </summary>
|
||||
/// <param name="input">Byte array to hash</param>
|
||||
/// <param name="hashType">Hash type to get from the file</param>
|
||||
/// <returns>Hash on success, null on error</returns>
|
||||
public static byte[]? GetByteArrayHashArray(byte[] input, HashType hashType)
|
||||
{
|
||||
var hashes = GetStreamHashArrays(new MemoryStream(input), [hashType]);
|
||||
return hashes?[hashType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes from an input byte array
|
||||
/// </summary>
|
||||
@@ -161,6 +266,15 @@ namespace SabreTools.Hashing
|
||||
public static Dictionary<HashType, string?>? GetByteArrayHashes(byte[] input, HashType[] hashTypes)
|
||||
=> GetStreamHashes(new MemoryStream(input), hashTypes);
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes from an input byte array
|
||||
/// </summary>
|
||||
/// <param name="input">Byte array 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>
|
||||
public static Dictionary<HashType, byte[]?>? GetByteArrayHashArrays(byte[] input, HashType[] hashTypes)
|
||||
=> GetStreamHashArrays(new MemoryStream(input), hashTypes);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Stream Hashes
|
||||
@@ -170,13 +284,27 @@ namespace SabreTools.Hashing
|
||||
/// </summary>
|
||||
/// <param name="input">Stream to hash</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
public static Dictionary<HashType, string?>? GetStreamHashes(Stream input)
|
||||
public static Dictionary<HashType, string?>? GetStreamHashes(Stream input, bool leaveOpen = false)
|
||||
{
|
||||
// Create a hash array for all entries
|
||||
HashType[] hashTypes = (HashType[])Enum.GetValues(typeof(HashType));
|
||||
|
||||
// Get the output hashes
|
||||
return GetStreamHashes(input, hashTypes);
|
||||
return GetStreamHashes(input, hashTypes, leaveOpen);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get hashes from an input Stream
|
||||
/// </summary>
|
||||
/// <param name="input">Stream to hash</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
public static Dictionary<HashType, byte[]?>? GetStreamHashArrays(Stream input, bool leaveOpen = false)
|
||||
{
|
||||
// Create a hash array for all entries
|
||||
HashType[] hashTypes = (HashType[])Enum.GetValues(typeof(HashType));
|
||||
|
||||
// Get the output hashes
|
||||
return GetStreamHashArrays(input, hashTypes, leaveOpen);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -184,10 +312,22 @@ namespace SabreTools.Hashing
|
||||
/// </summary>
|
||||
/// <param name="input">Stream to hash</param>
|
||||
/// <param name="hashType">Hash type to get from the file</param>
|
||||
/// <returns>Dictionary containing hashes on success, null on error</returns>
|
||||
public static string? GetStreamHash(Stream input, HashType hashType)
|
||||
/// <returns>Hash on success, null on error</returns>
|
||||
public static string? GetStreamHash(Stream input, HashType hashType, bool leaveOpen = false)
|
||||
{
|
||||
var hashes = GetStreamHashes(input, [hashType]);
|
||||
var hashes = GetStreamHashes(input, [hashType], leaveOpen);
|
||||
return hashes?[hashType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a hash and size from an input Stream
|
||||
/// </summary>
|
||||
/// <param name="input">Stream to hash</param>
|
||||
/// <param name="hashType">Hash type to get from the file</param>
|
||||
/// <returns>Hash on success, null on error</returns>
|
||||
public static byte[]? GetStreamHashArray(Stream input, HashType hashType, bool leaveOpen = false)
|
||||
{
|
||||
var hashes = GetStreamHashArrays(input, [hashType], leaveOpen);
|
||||
return hashes?[hashType];
|
||||
}
|
||||
|
||||
@@ -197,7 +337,70 @@ 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>
|
||||
public static Dictionary<HashType, string?>? GetStreamHashes(Stream input, HashType[] hashTypes)
|
||||
public static Dictionary<HashType, string?>? GetStreamHashes(Stream input, HashType[] hashTypes, bool leaveOpen = false)
|
||||
{
|
||||
// Create the output dictionary
|
||||
var hashDict = new Dictionary<HashType, string?>();
|
||||
|
||||
// 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.CurrentHashString;
|
||||
}
|
||||
|
||||
// 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">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>
|
||||
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?>();
|
||||
@@ -213,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.CurrentHashString;
|
||||
}
|
||||
|
||||
// Dispose of the hashers
|
||||
loadBuffer.Dispose();
|
||||
foreach (var hasher in hashers.Values)
|
||||
{
|
||||
hasher.Dispose();
|
||||
}
|
||||
|
||||
return hashDict;
|
||||
return hashers;
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
@@ -297,7 +461,8 @@ namespace SabreTools.Hashing
|
||||
}
|
||||
finally
|
||||
{
|
||||
input.Dispose();
|
||||
if (!leaveOpen)
|
||||
input.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,23 +5,86 @@ namespace SabreTools.Hashing
|
||||
/// </summary>
|
||||
public enum HashType
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark Adler's 32-bit checksum
|
||||
/// </summary>
|
||||
Adler32,
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// BLAKE3 512-bit digest
|
||||
/// </summary>
|
||||
BLAKE3,
|
||||
#endif
|
||||
|
||||
// <summary>
|
||||
/// CRC 16-bit checksum using the CCITT polynomial
|
||||
/// </summary>
|
||||
CRC16_CCITT,
|
||||
|
||||
// <summary>
|
||||
/// CRC 16-bit checksum using the IBM polynomial
|
||||
/// </summary>
|
||||
CRC16_IBM,
|
||||
|
||||
/// <summary>
|
||||
/// CRC 32-bit checksum
|
||||
/// </summary>
|
||||
/// <remarks>Same as CRC32_ISO in .NET Framework 4.5.2 and lower</remarks>
|
||||
CRC32,
|
||||
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
/// <summary>
|
||||
/// CRC 64-bit checksum
|
||||
/// CRC 32-bit checksum (ISO implementation)
|
||||
/// </summary>
|
||||
CRC32_ISO,
|
||||
|
||||
/// <summary>
|
||||
/// CRC 32-bit checksum (NaiveCRC implementation)
|
||||
/// </summary>
|
||||
CRC32_Naive,
|
||||
|
||||
/// <summary>
|
||||
/// CRC 32-bit checksum (OptimizedCRC implementation)
|
||||
/// </summary>
|
||||
CRC32_Optimized,
|
||||
|
||||
/// <summary>
|
||||
/// CRC 32-bit checksum (ParallelCRC implementation)
|
||||
/// </summary>
|
||||
CRC32_Parallel,
|
||||
|
||||
/// <summary>
|
||||
/// CRC 64-bit checksum (0x42F0E1EBA9EA3693 polynomial)
|
||||
/// </summary>
|
||||
CRC64,
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// CRC 64-bit checksum (0xC96C5795D7870F42 polynomial)
|
||||
/// </summary>
|
||||
CRC64_Reversed,
|
||||
|
||||
/// <summary>
|
||||
/// John G. Fletcher's 16-bit checksum
|
||||
/// </summary>
|
||||
Fletcher16,
|
||||
|
||||
/// <summary>
|
||||
/// John G. Fletcher's 32-bit checksum
|
||||
/// </summary>
|
||||
Fletcher32,
|
||||
|
||||
/// <summary>
|
||||
/// MD5 hash
|
||||
/// </summary>
|
||||
MD5,
|
||||
|
||||
#if NETFRAMEWORK
|
||||
/// <summary>
|
||||
/// RIPEMD160 hash
|
||||
/// </summary>
|
||||
RIPEMD160,
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// SHA-1 hash
|
||||
/// </summary>
|
||||
@@ -42,6 +105,35 @@ namespace SabreTools.Hashing
|
||||
/// </summary>
|
||||
SHA512,
|
||||
|
||||
#if NET8_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// SHA3-256 hash
|
||||
/// </summary>
|
||||
SHA3_256,
|
||||
|
||||
/// <summary>
|
||||
/// SHA3-384 hash
|
||||
/// </summary>
|
||||
SHA3_384,
|
||||
|
||||
/// <summary>
|
||||
/// SHA3-512 hash
|
||||
/// </summary>
|
||||
SHA3_512,
|
||||
|
||||
/// <summary>
|
||||
/// SHAKE128 SHA-3 family hash
|
||||
/// </summary>
|
||||
/// <remarks>Outputs a 256-bit (32-byte) hash</remarks>
|
||||
SHAKE128,
|
||||
|
||||
/// <summary>
|
||||
/// SHAKE256 SHA-3 family hash
|
||||
/// </summary>
|
||||
/// <remarks>Outputs a 512-bit (64-byte) hash</remarks>
|
||||
SHAKE256,
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// spamsum fuzzy hash
|
||||
/// </summary>
|
||||
|
||||
@@ -2,12 +2,14 @@ using System;
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
using System.IO.Hashing;
|
||||
#endif
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Security.Cryptography;
|
||||
using Aaru.Checksums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
#if NET7_0_OR_GREATER
|
||||
using Blake3;
|
||||
#endif
|
||||
using CRC32;
|
||||
|
||||
namespace SabreTools.Hashing
|
||||
{
|
||||
@@ -21,11 +23,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
|
||||
@@ -38,8 +36,15 @@ namespace SabreTools.Hashing
|
||||
{
|
||||
HashAlgorithm ha => ha.Hash,
|
||||
IChecksum ic => ic.Final(),
|
||||
NaiveCRC ncrc => BitConverter.GetBytes(ncrc.Value).Reverse().ToArray(),
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
NonCryptographicHashAlgorithm ncha => ncha.GetCurrentHash().Reverse().ToArray(),
|
||||
#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),
|
||||
#endif
|
||||
_ => null,
|
||||
};
|
||||
@@ -71,6 +76,11 @@ 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
|
||||
@@ -92,17 +102,44 @@ 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.CRC32 => new OptimizedCRC.OptimizedCRC(),
|
||||
HashType.CRC64 => new Crc64Context(CRC64_ECMA_POLY_NORMAL, 0xFFFFFFFFFFFFFFFF),
|
||||
#endif
|
||||
HashType.CRC64_Reversed => new Crc64Context(),
|
||||
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(),
|
||||
HashType.SHA512 => SHA512.Create(),
|
||||
#if NET8_0_OR_GREATER
|
||||
HashType.SHA3_256 => SHA3_256.IsSupported ? SHA3_256.Create() : null,
|
||||
HashType.SHA3_384 => SHA3_384.IsSupported ? SHA3_384.Create() : null,
|
||||
HashType.SHA3_512 => SHA3_512.IsSupported ? SHA3_512.Create() : null,
|
||||
HashType.SHAKE128 => Shake128.IsSupported ? new Shake128() : null,
|
||||
HashType.SHAKE256 => Shake256.IsSupported ? new Shake256() : null,
|
||||
#endif
|
||||
HashType.SpamSum => new SpamSumContext(),
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
HashType.XxHash32 => new XxHash32(),
|
||||
@@ -141,15 +178,35 @@ namespace SabreTools.Hashing
|
||||
ic.Update(icBuffer);
|
||||
break;
|
||||
|
||||
case NaiveCRC nc:
|
||||
nc.Update(buffer, offset, size);
|
||||
break;
|
||||
|
||||
#if NET462_OR_GREATER || NETCOREAPP
|
||||
case NonCryptographicHashAlgorithm ncha:
|
||||
var nchaBufferSpan = new ReadOnlySpan<byte>(buffer, offset, size);
|
||||
ncha.Append(nchaBufferSpan);
|
||||
break;
|
||||
#else
|
||||
case OptimizedCRC.OptimizedCRC oc:
|
||||
#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);
|
||||
s128.AppendData(s128BufferSpan);
|
||||
break;
|
||||
|
||||
case Shake256 s256:
|
||||
var s256BufferSpan = new ReadOnlySpan<byte>(buffer, offset, size);
|
||||
s256.AppendData(s256BufferSpan);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -157,7 +214,7 @@ namespace SabreTools.Hashing
|
||||
/// <summary>
|
||||
/// Finalize the internal hash algorigthm
|
||||
/// </summary>
|
||||
/// <remarks>NonCryptographicHashAlgorithm implementations do not need finalization</remarks>
|
||||
/// <remarks>NonCryptographicHashAlgorithm, SHAKE128, and SHAKE256 implementations do not need finalization</remarks>
|
||||
public void Terminate()
|
||||
{
|
||||
byte[] emptyBuffer = [];
|
||||
@@ -167,11 +224,17 @@ namespace SabreTools.Hashing
|
||||
ha.TransformFinalBlock(emptyBuffer, 0, 0);
|
||||
break;
|
||||
|
||||
#if NET20_OR_GREATER || NETCOREAPP3_1 || NET5_0
|
||||
case OptimizedCRC.OptimizedCRC oc:
|
||||
case NaiveCRC nc:
|
||||
nc.Update([], 0, 0);
|
||||
break;
|
||||
|
||||
case OptimizedCRC oc:
|
||||
oc.Update([], 0, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ParallelCRC pc:
|
||||
pc.Update([], 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.1.2</Version>
|
||||
<Version>1.2.2</Version>
|
||||
<WarningsNotAsErrors>NU5104</WarningsNotAsErrors>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
@@ -28,6 +29,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<!-- 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" />
|
||||
@@ -39,5 +43,12 @@
|
||||
<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>
|
||||
|
||||
524
SabreTools.Hashing/Tiger/SBoxes.cs
Normal file
524
SabreTools.Hashing/Tiger/SBoxes.cs
Normal 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 */
|
||||
];
|
||||
}
|
||||
}
|
||||
185
SabreTools.Hashing/Tiger/TigerHash.cs
Normal file
185
SabreTools.Hashing/Tiger/TigerHash.cs
Normal file
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
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 = str.Skip(strOffset).Take(8).ToArray();
|
||||
|
||||
// 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
36
publish-nix.sh
Normal 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
26
publish-win.ps1
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user