Code refactor and cleanup.

This commit is contained in:
2022-12-02 15:33:35 +00:00
parent b1b002b15f
commit 3b83219146
33 changed files with 6879 additions and 6995 deletions

View File

@@ -50,24 +50,24 @@
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System"/>
</ItemGroup>
<ItemGroup>
<Compile Include="Adler32\neon.cs" />
<Compile Include="Adler32\ssse3.cs" />
<Compile Include="CRC16CCITTContext.cs" />
<Compile Include="CRC16IBMContext.cs" />
<Compile Include="CRC32\clmul.cs" />
<Compile Include="CRC32\arm_simd.cs" />
<Compile Include="CRC32\vmull.cs" />
<Compile Include="CRC64\clmul.cs" />
<Compile Include="Native.cs" />
<Compile Include="SpamSumContext.cs" />
<Compile Include="Adler32Context.cs" />
<Compile Include="CRC16Context.cs" />
<Compile Include="CRC32Context.cs" />
<Compile Include="CRC64Context.cs" />
<Compile Include="FletcherContext.cs" />
<Compile Include="Adler32\neon.cs"/>
<Compile Include="Adler32\ssse3.cs"/>
<Compile Include="CRC16CCITTContext.cs"/>
<Compile Include="CRC16IBMContext.cs"/>
<Compile Include="CRC32\clmul.cs"/>
<Compile Include="CRC32\arm_simd.cs"/>
<Compile Include="CRC32\vmull.cs"/>
<Compile Include="CRC64\clmul.cs"/>
<Compile Include="Native.cs"/>
<Compile Include="SpamSumContext.cs"/>
<Compile Include="Adler32Context.cs"/>
<Compile Include="CRC16Context.cs"/>
<Compile Include="CRC32Context.cs"/>
<Compile Include="CRC64Context.cs"/>
<Compile Include="FletcherContext.cs"/>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\LICENSE.LGPL">
@@ -75,17 +75,17 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Aaru.Checksums.Native" Version="6.0.0-alpha9" />
<PackageReference Include="Aaru.CommonTypes" Version="5.3.1" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3" PrivateAssets="all" />
<PackageReference Include="Aaru.Checksums.Native" Version="6.0.0-alpha9"/>
<PackageReference Include="Aaru.CommonTypes" Version="5.3.1"/>
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3" PrivateAssets="all"/>
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties>
<Policies>
<StandardHeader IncludeInNewFiles="True" Text="/***************************************************************************&#xA;Aaru Data Preservation Suite&#xA;----------------------------------------------------------------------------&#xA; &#xA;Filename : ${FileName}&#xA;Author(s) : ${AuthorName} &lt;${AuthorEmail}&gt;&#xA;&#xA;Component : Component&#xA; &#xA;--[ Description ] ----------------------------------------------------------&#xA; &#xA; Description&#xA; &#xA;--[ License ] --------------------------------------------------------------&#xA; &#xA; This library is free software; you can redistribute it and/or modify&#xA; it under the terms of the GNU Lesser General Public License as&#xA; published by the Free Software Foundation; either version 2.1 of the&#xA; License, or (at your option) any later version.&#xA;&#xA; This library is distributed in the hope that it will be useful, but&#xA; WITHOUT ANY WARRANTY; without even the implied warranty of&#xA; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU&#xA; Lesser General Public License for more details.&#xA;&#xA; You should have received a copy of the GNU Lesser General Public&#xA; License along with this library; if not, see &lt;http://www.gnu.org/licenses/&gt;.&#xA;&#xA;----------------------------------------------------------------------------&#xA;Copyright © 2011-${Year} ${CopyrightHolder}&#xA;****************************************************************************/" />
<TextStylePolicy FileWidth="120" TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" TabsToSpaces="True" scope="text/x-csharp" />
<CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="True" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" NewLinesForBracesInProperties="True" NewLinesForBracesInAccessors="True" NewLinesForBracesInAnonymousMethods="True" NewLinesForBracesInControlBlocks="True" NewLinesForBracesInAnonymousTypes="True" NewLinesForBracesInObjectCollectionArrayInitializers="True" NewLinesForBracesInLambdaExpressionBody="True" NewLineForElse="True" NewLineForCatch="True" NewLineForFinally="True" NewLineForMembersInObjectInit="True" NewLineForMembersInAnonymousTypes="True" NewLineForClausesInQuery="True" SpacingAfterMethodDeclarationName="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceAfterMethodCallName="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBeforeOpenSquareBracket="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeColonInBaseTypeDeclaration="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" SpaceAfterControlFlowStatementKeyword="False" scope="text/x-csharp" />
<StandardHeader IncludeInNewFiles="True" Text="/***************************************************************************&#xA;Aaru Data Preservation Suite&#xA;----------------------------------------------------------------------------&#xA; &#xA;Filename : ${FileName}&#xA;Author(s) : ${AuthorName} &lt;${AuthorEmail}&gt;&#xA;&#xA;Component : Component&#xA; &#xA;--[ Description ] ----------------------------------------------------------&#xA; &#xA; Description&#xA; &#xA;--[ License ] --------------------------------------------------------------&#xA; &#xA; This library is free software; you can redistribute it and/or modify&#xA; it under the terms of the GNU Lesser General Public License as&#xA; published by the Free Software Foundation; either version 2.1 of the&#xA; License, or (at your option) any later version.&#xA;&#xA; This library is distributed in the hope that it will be useful, but&#xA; WITHOUT ANY WARRANTY; without even the implied warranty of&#xA; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU&#xA; Lesser General Public License for more details.&#xA;&#xA; You should have received a copy of the GNU Lesser General Public&#xA; License along with this library; if not, see &lt;http://www.gnu.org/licenses/&gt;.&#xA;&#xA;----------------------------------------------------------------------------&#xA;Copyright © 2011-${Year} ${CopyrightHolder}&#xA;****************************************************************************/"/>
<TextStylePolicy FileWidth="120" TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" TabsToSpaces="True" scope="text/x-csharp"/>
<CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="True" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" NewLinesForBracesInProperties="True" NewLinesForBracesInAccessors="True" NewLinesForBracesInAnonymousMethods="True" NewLinesForBracesInControlBlocks="True" NewLinesForBracesInAnonymousTypes="True" NewLinesForBracesInObjectCollectionArrayInitializers="True" NewLinesForBracesInLambdaExpressionBody="True" NewLineForElse="True" NewLineForCatch="True" NewLineForFinally="True" NewLineForMembersInObjectInit="True" NewLineForMembersInAnonymousTypes="True" NewLineForClausesInQuery="True" SpacingAfterMethodDeclarationName="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceAfterMethodCallName="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBeforeOpenSquareBracket="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeColonInBaseTypeDeclaration="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" SpaceAfterControlFlowStatementKeyword="False" scope="text/x-csharp"/>
</Policies>
</Properties>
</MonoDevelop>

View File

@@ -48,177 +48,176 @@
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
namespace Aaru6.Checksums.Adler32
namespace Aaru6.Checksums.Adler32;
internal static class neon
{
internal static class neon
internal static void Step(ref ushort preSum1, ref ushort preSum2, byte[] buf, uint len)
{
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;
int bufPos = 0;
/*
* Process the data in blocks.
*/
uint BLOCK_SIZE = 1 << 5;
uint blocks = len / BLOCK_SIZE;
len -= blocks * BLOCK_SIZE;
while(blocks != 0)
{
uint n = Adler32Context.NMAX / BLOCK_SIZE; /* The NMAX constraint. */
if(n > blocks)
n = blocks;
blocks -= n;
/*
* Split Adler-32 into component sums.
* Process n blocks of data. At most NMAX data bytes can be
* processed before s2 must be reduced modulo ADLER_MODULE.
*/
uint s1 = preSum1;
uint s2 = preSum2;
Vector128<uint> v_s2 = Vector128.Create(s1 * n, 0, 0, 0);
Vector128<uint> 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);
int bufPos = 0;
/*
* Process the data in blocks.
*/
uint BLOCK_SIZE = 1 << 5;
uint blocks = len / BLOCK_SIZE;
len -= blocks * BLOCK_SIZE;
while(blocks != 0)
do
{
uint n = Adler32Context.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 ADLER_MODULE.
* Load 32 input bytes.
*/
Vector128<uint> v_s2 = Vector128.Create(s1 * n, 0, 0, 0);
Vector128<uint> 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);
Vector128<byte> 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]);
do
{
/*
* Load 32 input bytes.
*/
Vector128<byte> 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;
bufPos += 16;
Vector128<byte> 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]);
Vector128<byte> 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);
bufPos += 16;
/*
* Add previous block byte sum to v_s2.
*/
v_s2 = AdvSimd.Add(v_s2, v_s1);
/*
* Multiply-add bytes by [ 32, 31, 30, ... ] for s2.
* Horizontally add the bytes for s1.
*/
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));
v_s1 =
AdvSimd.AddPairwiseWideningAndAdd(v_s1,
AdvSimd.
AddPairwiseWideningAndAdd(AdvSimd.AddPairwiseWidening(bytes1),
bytes2));
/*
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
* Vertically add the bytes for 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 %= Adler32Context.ADLER_MODULE;
s2 %= Adler32Context.ADLER_MODULE;
}
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);
/*
* Handle leftover data.
* Multiply-add bytes by [ 32, 31, 30, ... ] for s2.
*/
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;
}
v_s2 = AdvSimd.MultiplyWideningLowerAndAdd(v_s2, v_column_sum_1.GetLower(),
Vector64.Create((ushort)32, 31, 30, 29));
while(len-- != 0)
{
s2 += s1 += buf[bufPos++];
}
v_s2 = AdvSimd.MultiplyWideningLowerAndAdd(v_s2, v_column_sum_1.GetUpper(),
Vector64.Create((ushort)28, 27, 26, 25));
if(s1 >= Adler32Context.ADLER_MODULE)
s1 -= Adler32Context.ADLER_MODULE;
v_s2 = AdvSimd.MultiplyWideningLowerAndAdd(v_s2, v_column_sum_2.GetLower(),
Vector64.Create((ushort)24, 23, 22, 21));
s2 %= Adler32Context.ADLER_MODULE;
}
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));
/*
* Return the recombined sums.
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
*/
preSum1 = (ushort)(s1 & 0xFFFF);
preSum2 = (ushort)(s2 & 0xFFFF);
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 %= 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);
}
}

View File

@@ -49,138 +49,137 @@ using System;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
namespace Aaru6.Checksums.Adler32
namespace Aaru6.Checksums.Adler32;
internal static class ssse3
{
internal static class ssse3
internal static void Step(ref ushort sum1, ref ushort sum2, byte[] buf, uint len)
{
internal static void Step(ref ushort sum1, ref ushort sum2, byte[] buf, uint len)
uint s1 = sum1;
uint s2 = sum2;
int bufPos = 0;
/*
* Process the data in blocks.
*/
uint BLOCK_SIZE = 1 << 5;
uint blocks = len / BLOCK_SIZE;
len -= blocks * BLOCK_SIZE;
while(blocks != 0)
{
uint s1 = sum1;
uint s2 = sum2;
int bufPos = 0;
uint n = Adler32Context.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();
Vector128<short> ones = Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1);
/*
* Process the data in blocks.
* Process n blocks of data. At most NMAX data bytes can be
* processed before s2 must be reduced modulo BASE.
*/
uint BLOCK_SIZE = 1 << 5;
uint blocks = len / BLOCK_SIZE;
len -= blocks * BLOCK_SIZE;
Vector128<uint> v_ps = Vector128.Create(s1 * n, 0, 0, 0);
Vector128<uint> v_s2 = Vector128.Create(s2, 0, 0, 0);
Vector128<uint> v_s1 = Vector128.Create(0u, 0, 0, 0);
while(blocks != 0)
do
{
uint n = Adler32Context.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();
Vector128<short> 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.
* Load 32 input bytes.
*/
Vector128<uint> v_ps = Vector128.Create(s1 * n, 0, 0, 0);
Vector128<uint> v_s2 = Vector128.Create(s2, 0, 0, 0);
Vector128<uint> v_s1 = Vector128.Create(0u, 0, 0, 0);
Vector128<uint> bytes1 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
BitConverter.ToUInt32(buf, bufPos + 4),
BitConverter.ToUInt32(buf, bufPos + 8),
BitConverter.ToUInt32(buf, bufPos + 12));
do
{
/*
* Load 32 input bytes.
*/
Vector128<uint> bytes1 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
BitConverter.ToUInt32(buf, bufPos + 4),
BitConverter.ToUInt32(buf, bufPos + 8),
BitConverter.ToUInt32(buf, bufPos + 12));
bufPos += 16;
bufPos += 16;
Vector128<uint> bytes2 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
BitConverter.ToUInt32(buf, bufPos + 4),
BitConverter.ToUInt32(buf, bufPos + 8),
BitConverter.ToUInt32(buf, bufPos + 12));
Vector128<uint> bytes2 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
BitConverter.ToUInt32(buf, bufPos + 4),
BitConverter.ToUInt32(buf, bufPos + 8),
BitConverter.ToUInt32(buf, bufPos + 12));
bufPos += 16;
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 = 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 = 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).
* Add previous block byte sum to v_ps.
*/
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());
v_ps = Sse2.Add(v_ps, v_s1);
/*
* Reduce.
* Horizontally add the bytes for s1, multiply-adds the
* bytes by [ 32, 31, 30, ... ] for s2.
*/
s1 %= Adler32Context.ADLER_MODULE;
s2 %= Adler32Context.ADLER_MODULE;
}
v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes1.AsByte(), zero).AsUInt32());
Vector128<short> mad1 = 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 = 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));
/*
* Handle leftover data.
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
*/
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;
}
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());
/*
* Return the recombined sums.
* Reduce.
*/
sum1 = (ushort)(s1 & 0xFFFF);
sum2 = (ushort)(s2 & 0xFFFF);
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);
}
}

View File

@@ -46,363 +46,363 @@ using Aaru.CommonTypes.Interfaces;
using Aaru.Helpers;
using Aaru6.Checksums.Adler32;
namespace Aaru6.Checksums
namespace Aaru6.Checksums;
/// <inheritdoc />
/// <summary>Implements the Adler-32 algorithm</summary>
public sealed class Adler32Context : IChecksum
{
/// <inheritdoc />
/// <summary>Implements the Adler-32 algorithm</summary>
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()
{
internal const ushort ADLER_MODULE = 65521;
internal const uint NMAX = 5552;
ushort _sum1, _sum2;
readonly bool _useNative;
readonly IntPtr _nativeContext;
_sum1 = 1;
_sum2 = 0;
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern IntPtr adler32_init();
if(!Native.IsSupported)
return;
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int adler32_update(IntPtr ctx, byte[] data, uint len);
_nativeContext = adler32_init();
_useNative = _nativeContext != IntPtr.Zero;
}
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int adler32_final(IntPtr ctx, ref uint checksum);
/// <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);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern void adler32_free(IntPtr ctx);
/// <inheritdoc />
/// <summary>Updates the hash with data.</summary>
/// <param name="data">Data buffer.</param>
public void Update(byte[] data) => Update(data, (uint)data.Length);
/// <summary>Initializes the Adler-32 sums</summary>
public Adler32Context()
/// <inheritdoc />
/// <summary>Returns a byte array of the hash value.</summary>
public byte[] Final()
{
uint 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()
{
uint finalSum = (uint)((_sum2 << 16) | _sum1);
if(_useNative)
{
_sum1 = 1;
_sum2 = 0;
if(!Native.IsSupported)
return;
_nativeContext = adler32_init();
_useNative = _nativeContext != IntPtr.Zero;
}
/// <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()
{
uint 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 adlerOutput = new StringBuilder();
for(int i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
adlerOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
return adlerOutput.ToString();
}
[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)
{
uint finalSum = (uint)((_sum2 << 16) | _sum1);
adler32_update(nativeContext, data, len);
if(_useNative)
{
adler32_final(_nativeContext, ref finalSum);
adler32_free(_nativeContext);
}
var adlerOutput = new StringBuilder();
for(int i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
adlerOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
return adlerOutput.ToString();
return;
}
static void Step(ref ushort preSum1, ref ushort preSum2, byte[] data, uint len, bool useNative, IntPtr nativeContext)
if(Ssse3.IsSupported)
{
if(useNative)
{
adler32_update(nativeContext, data, len);
ssse3.Step(ref preSum1, ref preSum2, data, len);
return;
}
return;
}
if(Ssse3.IsSupported)
{
ssse3.Step(ref preSum1, ref preSum2, data, len);
if(AdvSimd.IsSupported)
{
neon.Step(ref preSum1, ref preSum2, data, len);
return;
}
return;
}
if(AdvSimd.IsSupported)
{
neon.Step(ref preSum1, ref preSum2, data, len);
uint sum1 = preSum1;
uint sum2 = preSum2;
uint n;
int dataOff = 0;
return;
}
/* in case user likes doing a byte at a time, keep it fast */
if(len == 1)
{
sum1 += data[dataOff];
uint sum1 = preSum1;
uint sum2 = preSum2;
uint n;
int dataOff = 0;
if(sum1 >= ADLER_MODULE)
sum1 -= ADLER_MODULE;
/* in case user likes doing a byte at a time, keep it fast */
if(len == 1)
{
sum1 += data[dataOff];
sum2 += sum1;
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 */
if(len < 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;
n = NMAX / 16; /* NMAX is divisible by 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;
}
if(sum2 >= ADLER_MODULE)
sum2 -= ADLER_MODULE;
preSum1 = (ushort)(sum1 & 0xFFFF);
preSum2 = (ushort)(sum2 & 0xFFFF);
return;
}
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
public static byte[] File(string filename)
/* in case short lengths are provided, keep it somewhat fast */
if(len < 16)
{
File(filename, out byte[] hash);
while(len-- > 0)
{
sum1 += data[dataOff++];
sum2 += sum1;
}
return hash;
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;
}
/// <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)
/* do length NMAX blocks -- requires just one modulo operation */
while(len >= NMAX)
{
bool useNative = Native.IsSupported;
IntPtr nativeContext = IntPtr.Zero;
len -= NMAX;
n = NMAX / 16; /* NMAX is divisible by 16 */
if(useNative)
do
{
nativeContext = adler32_init();
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;
if(nativeContext == IntPtr.Zero)
useNative = false;
}
/* 16 sums unrolled */
dataOff += 16;
} while(--n != 0);
var fileStream = new FileStream(filename, FileMode.Open);
ushort localSum1 = 1;
ushort localSum2 = 0;
byte[] buffer = new byte[65536];
int read = fileStream.Read(buffer, 0, 65536);
while(read > 0)
{
Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
read = fileStream.Read(buffer, 0, 65536);
}
uint 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();
sum1 %= ADLER_MODULE;
sum2 %= ADLER_MODULE;
}
/// <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)
/* do remaining bytes (less than NMAX, still just one modulo) */
if(len != 0)
{
bool useNative = Native.IsSupported;
IntPtr nativeContext = IntPtr.Zero;
if(useNative)
/* avoid modulos if none remaining */
while(len >= 16)
{
nativeContext = adler32_init();
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;
if(nativeContext == IntPtr.Zero)
useNative = false;
dataOff += 16;
}
ushort localSum1 = 1;
ushort localSum2 = 0;
Step(ref localSum1, ref localSum2, data, len, useNative, nativeContext);
uint finalSum = (uint)((localSum2 << 16) | localSum1);
if(useNative)
while(len-- != 0)
{
adler32_final(nativeContext, ref finalSum);
adler32_free(nativeContext);
sum1 += data[dataOff++];
sum2 += sum1;
}
hash = BigEndianBitConverter.GetBytes(finalSum);
var adlerOutput = new StringBuilder();
foreach(byte h in hash)
adlerOutput.Append(h.ToString("x2"));
return adlerOutput.ToString();
sum1 %= ADLER_MODULE;
sum2 %= ADLER_MODULE;
}
/// <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);
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;
byte[] buffer = new byte[65536];
int read = fileStream.Read(buffer, 0, 65536);
while(read > 0)
{
Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
read = fileStream.Read(buffer, 0, 65536);
}
uint 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);
uint 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);
}

View File

@@ -30,238 +30,237 @@
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
namespace Aaru6.Checksums
namespace Aaru6.Checksums;
/// <inheritdoc />
/// <summary>Implements the CRC16 algorithm with CCITT polynomial and seed</summary>
public sealed class CRC16CCITTContext : Crc16Context
{
/// <inheritdoc />
/// <summary>Implements the CRC16 algorithm with CCITT polynomial and seed</summary>
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 =
{
/// <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[]
{
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) {}
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
public static byte[] File(string filename)
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[]
{
File(filename, out byte[] hash);
return hash;
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>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>Initializes an instance of the CRC16 with CCITT polynomial and seed.</summary>
/// <inheritdoc />
public CRC16CCITTContext() : base(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 a file</summary>
/// <param name="filename">File path.</param>
public static byte[] File(string filename)
{
File(filename, out byte[] hash);
/// <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);
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);
}

File diff suppressed because it is too large Load Diff

View File

@@ -30,232 +30,231 @@
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
namespace Aaru6.Checksums
namespace Aaru6.Checksums;
/// <inheritdoc />
/// <summary>Implements the CRC16 algorithm with IBM polynomial and seed</summary>
public sealed class CRC16IBMContext : Crc16Context
{
/// <inheritdoc />
/// <summary>Implements the CRC16 algorithm with IBM polynomial and seed</summary>
public sealed class CRC16IBMContext : Crc16Context
internal const ushort CRC16_IBM_POLY = 0xA001;
internal const ushort CRC16_IBM_SEED = 0x0000;
static readonly ushort[][] _ibmCrc16Table =
{
internal const ushort CRC16_IBM_POLY = 0xA001;
internal const ushort CRC16_IBM_SEED = 0x0000;
static readonly ushort[][] _ibmCrc16Table =
new ushort[]
{
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) {}
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
public static byte[] File(string filename)
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[]
{
File(filename, out byte[] hash);
return hash;
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>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>Initializes an instance of the CRC16 with IBM polynomial and seed.</summary>
/// <inheritdoc />
public CRC16IBMContext() : base(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 a file</summary>
/// <param name="filename">File path.</param>
public static byte[] File(string filename)
{
File(filename, out byte[] hash);
/// <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);
return hash;
}
/// <summary>Gets the hash of a file in hexadecimal and as a byte array.</summary>
/// <param name="filename">File path.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string File(string filename, out byte[] hash) =>
File(filename, out hash, CRC16_IBM_POLY, CRC16_IBM_SEED, _ibmCrc16Table, false);
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="len">Length of the data buffer to hash.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, uint len, out byte[] hash) =>
Data(data, len, out hash, CRC16_IBM_POLY, CRC16_IBM_SEED, _ibmCrc16Table, false);
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="hash">Byte array of the hash value.</param>
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
}

View File

@@ -48,92 +48,91 @@
using System;
using System.Runtime.Intrinsics.Arm;
namespace Aaru6.Checksums.CRC32
namespace Aaru6.Checksums.CRC32;
internal static class ArmSimd
{
internal static class ArmSimd
internal static uint Step64(byte[] buf, long len, uint crc)
{
internal static uint Step64(byte[] buf, long len, uint crc)
uint c = crc;
int bufPos = 0;
while(len >= 64)
{
uint c = crc;
int 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;
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;
}
internal static uint Step32(byte[] buf, long len, uint crc)
while(len >= 8)
{
uint c = crc;
int 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;
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;
int 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;
}
}

View File

@@ -52,199 +52,192 @@ using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
namespace Aaru6.Checksums.CRC32
namespace Aaru6.Checksums.CRC32;
internal static class Clmul
{
internal static class Clmul
static readonly uint[] _crcK =
{
static readonly uint[] _crcK =
0xccaa009e, 0x00000000, /* rk1 */ 0x751997d0, 0x00000001, /* rk2 */ 0xccaa009e, 0x00000000, /* rk5 */
0x63cd6124, 0x00000001, /* rk6 */ 0xf7011640, 0x00000001, /* rk7 */ 0xdb710640, 0x00000001 /* rk8 */
};
static readonly Vector128<uint>[] _pshufbShfTable =
{
Vector128.Create(0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d), /* shl 15 (16 - 1)/shr1 */
Vector128.Create(0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e), /* shl 14 (16 - 3)/shr2 */
Vector128.Create(0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f), /* shl 13 (16 - 4)/shr3 */
Vector128.Create(0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100), /* shl 12 (16 - 4)/shr4 */
Vector128.Create(0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201), /* shl 11 (16 - 5)/shr5 */
Vector128.Create(0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302), /* shl 10 (16 - 6)/shr6 */
Vector128.Create(0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403), /* shl 9 (16 - 7)/shr7 */
Vector128.Create(0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504), /* shl 8 (16 - 8)/shr8 */
Vector128.Create(0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605), /* shl 7 (16 - 9)/shr9 */
Vector128.Create(0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706), /* shl 6 (16 -10)/shr10*/
Vector128.Create(0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807), /* shl 5 (16 -11)/shr11*/
Vector128.Create(0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908), /* shl 4 (16 -12)/shr12*/
Vector128.Create(0x008f8e8du, 0x04030201, 0x08070605, 0x0c0b0a09), /* shl 3 (16 -13)/shr13*/
Vector128.Create(0x01008f8eu, 0x05040302, 0x09080706, 0x0d0c0b0a), /* shl 2 (16 -14)/shr14*/
Vector128.Create(0x0201008fu, 0x06050403, 0x0a090807, 0x0e0d0c0b) /* shl 1 (16 -15)/shr15*/
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void Fold4(ref Vector128<uint> xmmCRC0, ref Vector128<uint> xmmCRC1, ref Vector128<uint> xmmCRC2,
ref Vector128<uint> xmmCRC3)
{
Vector128<uint> 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> xmmT0, xmmT1, xmmT2;
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;
int bufPos = 0;
bool first = true;
/* fold 512 to 32 step variable declarations for ISO-C90 compat. */
Vector128<uint> xmmMask = Vector128.Create(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000);
Vector128<uint> xmmMask2 = Vector128.Create(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
while((len -= 64) >= 0)
{
0xccaa009e, 0x00000000, /* rk1 */ 0x751997d0, 0x00000001, /* rk2 */ 0xccaa009e, 0x00000000, /* rk5 */
0x63cd6124, 0x00000001, /* rk6 */ 0xf7011640, 0x00000001, /* rk7 */ 0xdb710640, 0x00000001 /* rk8 */
};
xmmT0 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12));
static readonly Vector128<uint>[] _pshufbShfTable =
{
Vector128.Create(0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d), /* shl 15 (16 - 1)/shr1 */
Vector128.Create(0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e), /* shl 14 (16 - 3)/shr2 */
Vector128.Create(0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f), /* shl 13 (16 - 4)/shr3 */
Vector128.Create(0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100), /* shl 12 (16 - 4)/shr4 */
Vector128.Create(0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201), /* shl 11 (16 - 5)/shr5 */
Vector128.Create(0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302), /* shl 10 (16 - 6)/shr6 */
Vector128.Create(0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403), /* shl 9 (16 - 7)/shr7 */
Vector128.Create(0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504), /* shl 8 (16 - 8)/shr8 */
Vector128.Create(0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605), /* shl 7 (16 - 9)/shr9 */
Vector128.Create(0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706), /* shl 6 (16 -10)/shr10*/
Vector128.Create(0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807), /* shl 5 (16 -11)/shr11*/
Vector128.Create(0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908), /* shl 4 (16 -12)/shr12*/
Vector128.Create(0x008f8e8du, 0x04030201, 0x08070605, 0x0c0b0a09), /* shl 3 (16 -13)/shr13*/
Vector128.Create(0x01008f8eu, 0x05040302, 0x09080706, 0x0d0c0b0a), /* shl 2 (16 -14)/shr14*/
Vector128.Create(0x0201008fu, 0x06050403, 0x0a090807, 0x0e0d0c0b) /* shl 1 (16 -15)/shr15*/
};
bufPos += 16;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void Fold4(ref Vector128<uint> xmmCRC0, ref Vector128<uint> xmmCRC1, ref Vector128<uint> xmmCRC2,
ref Vector128<uint> xmmCRC3)
{
Vector128<uint> xmmFold4 = Vector128.Create(0xc6e41596, 0x00000001, 0x54442bd4, 0x00000001);
xmmT1 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12));
Vector128<uint> xTmp0 = xmmCRC0;
Vector128<uint> xTmp1 = xmmCRC1;
Vector128<uint> xTmp2 = xmmCRC2;
Vector128<uint> xTmp3 = xmmCRC3;
bufPos += 16;
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);
xmmT2 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12));
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);
bufPos += 16;
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);
Vector128<uint> xmmT3 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8),
BitConverter.ToUInt32(src, bufPos + 12));
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);
bufPos += 16;
xmmCRC0 = psRes0.AsUInt32();
xmmCRC1 = psRes1.AsUInt32();
xmmCRC2 = psRes2.AsUInt32();
xmmCRC3 = psRes3.AsUInt32();
}
internal static uint Step(byte[] src, long len, uint initialCRC)
{
Vector128<uint> xmmT0, xmmT1, xmmT2;
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;
int bufPos = 0;
bool first = true;
/* fold 512 to 32 step variable declarations for ISO-C90 compat. */
Vector128<uint> xmmMask = Vector128.Create(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000);
Vector128<uint> xmmMask2 = Vector128.Create(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
while((len -= 64) >= 0)
if(first)
{
xmmT0 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8),
BitConverter.ToUInt32(src, bufPos + 12));
bufPos += 16;
xmmT1 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8),
BitConverter.ToUInt32(src, bufPos + 12));
bufPos += 16;
xmmT2 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8),
BitConverter.ToUInt32(src, bufPos + 12));
bufPos += 16;
Vector128<uint> 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);
first = false;
xmmT0 = Sse2.Xor(xmmT0, xmmInitial);
}
/* fold 512 to 32 */
Fold4(ref xmmCRC0, ref xmmCRC1, ref xmmCRC2, ref xmmCRC3);
/*
* k1
*/
Vector128<uint> 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);
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
*/
Vector128<uint> 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);
}
}

View File

@@ -52,354 +52,352 @@ using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
namespace Aaru6.Checksums.CRC32
namespace Aaru6.Checksums.CRC32;
internal static class Vmull
{
internal static class Vmull
static readonly uint[] _crcK =
{
static readonly uint[] _crcK =
0xccaa009e, 0x00000000, /* rk1 */ 0x751997d0, 0x00000001, /* rk2 */ 0xccaa009e, 0x00000000, /* rk5 */
0x63cd6124, 0x00000001, /* rk6 */ 0xf7011640, 0x00000001, /* rk7 */ 0xdb710640, 0x00000001 /* rk8 */
};
static readonly Vector128<uint>[] _pshufbShfTable =
{
Vector128.Create(0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d), /* shl 15 (16 - 1)/shr1 */
Vector128.Create(0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e), /* shl 14 (16 - 3)/shr2 */
Vector128.Create(0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f), /* shl 13 (16 - 4)/shr3 */
Vector128.Create(0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100), /* shl 12 (16 - 4)/shr4 */
Vector128.Create(0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201), /* shl 11 (16 - 5)/shr5 */
Vector128.Create(0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302), /* shl 10 (16 - 6)/shr6 */
Vector128.Create(0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403), /* shl 9 (16 - 7)/shr7 */
Vector128.Create(0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504), /* shl 8 (16 - 8)/shr8 */
Vector128.Create(0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605), /* shl 7 (16 - 9)/shr9 */
Vector128.Create(0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706), /* shl 6 (16 -10)/shr10*/
Vector128.Create(0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807), /* shl 5 (16 -11)/shr11*/
Vector128.Create(0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908), /* shl 4 (16 -12)/shr12*/
Vector128.Create(0x008f8e8du, 0x04030201, 0x08070605, 0x0c0b0a09), /* shl 3 (16 -13)/shr13*/
Vector128.Create(0x01008f8eu, 0x05040302, 0x09080706, 0x0d0c0b0a), /* shl 2 (16 -14)/shr14*/
Vector128.Create(0x0201008fu, 0x06050403, 0x0a090807, 0x0e0d0c0b) /* shl 1 (16 -15)/shr15*/
};
static Vector128<ulong> vmull_p64(Vector64<ulong> a, Vector64<ulong> b)
{
if(Aes.IsSupported)
{
0xccaa009e, 0x00000000, /* rk1 */ 0x751997d0, 0x00000001, /* rk2 */ 0xccaa009e, 0x00000000, /* rk5 */
0x63cd6124, 0x00000001, /* rk6 */ 0xf7011640, 0x00000001, /* rk7 */ 0xdb710640, 0x00000001 /* rk8 */
};
static readonly Vector128<uint>[] _pshufbShfTable =
{
Vector128.Create(0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d), /* shl 15 (16 - 1)/shr1 */
Vector128.Create(0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e), /* shl 14 (16 - 3)/shr2 */
Vector128.Create(0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f), /* shl 13 (16 - 4)/shr3 */
Vector128.Create(0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100), /* shl 12 (16 - 4)/shr4 */
Vector128.Create(0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201), /* shl 11 (16 - 5)/shr5 */
Vector128.Create(0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302), /* shl 10 (16 - 6)/shr6 */
Vector128.Create(0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403), /* shl 9 (16 - 7)/shr7 */
Vector128.Create(0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504), /* shl 8 (16 - 8)/shr8 */
Vector128.Create(0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605), /* shl 7 (16 - 9)/shr9 */
Vector128.Create(0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706), /* shl 6 (16 -10)/shr10*/
Vector128.Create(0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807), /* shl 5 (16 -11)/shr11*/
Vector128.Create(0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908), /* shl 4 (16 -12)/shr12*/
Vector128.Create(0x008f8e8du, 0x04030201, 0x08070605, 0x0c0b0a09), /* shl 3 (16 -13)/shr13*/
Vector128.Create(0x01008f8eu, 0x05040302, 0x09080706, 0x0d0c0b0a), /* shl 2 (16 -14)/shr14*/
Vector128.Create(0x0201008fu, 0x06050403, 0x0a090807, 0x0e0d0c0b) /* shl 1 (16 -15)/shr15*/
};
static Vector128<ulong> vmull_p64(Vector64<ulong> a, Vector64<ulong> b)
{
if(Aes.IsSupported)
{
return Aes.PolynomialMultiplyWideningLower(a, b);
}
// Masks
Vector128<byte> k4832 = Vector128.Create(Vector64.Create(0x0000fffffffffffful),
Vector64.Create(0x00000000fffffffful)).AsByte();
Vector128<byte> k1600 = Vector128.Create(Vector64.Create(0x000000000000fffful),
Vector64.Create(0x0000000000000000ul)).AsByte();
// Do the multiplies, rotating with vext to get all combinations
Vector128<byte> d = AdvSimd.PolynomialMultiplyWideningLower(a.AsByte(), b.AsByte()).AsByte(); // D = A0 * B0
Vector128<byte> e = AdvSimd.
PolynomialMultiplyWideningLower(a.AsByte(),
AdvSimd.ExtractVector64(b.AsByte(), b.AsByte(), 1)).
AsByte(); // E = A0 * B1
Vector128<byte> f = AdvSimd.
PolynomialMultiplyWideningLower(AdvSimd.ExtractVector64(a.AsByte(), a.AsByte(), 1),
b.AsByte()).AsByte(); // F = A1 * B0
Vector128<byte> g = AdvSimd.
PolynomialMultiplyWideningLower(a.AsByte(),
AdvSimd.ExtractVector64(b.AsByte(), b.AsByte(), 2)).
AsByte(); // G = A0 * B2
Vector128<byte> h = AdvSimd.
PolynomialMultiplyWideningLower(AdvSimd.ExtractVector64(a.AsByte(), a.AsByte(), 2),
b.AsByte()).AsByte(); // H = A2 * B0
Vector128<byte> i = AdvSimd.
PolynomialMultiplyWideningLower(a.AsByte(),
AdvSimd.ExtractVector64(b.AsByte(), b.AsByte(), 3)).
AsByte(); // I = A0 * B3
Vector128<byte> j = AdvSimd.
PolynomialMultiplyWideningLower(AdvSimd.ExtractVector64(a.AsByte(), a.AsByte(), 3),
b.AsByte()).AsByte(); // J = A3 * B0
Vector128<byte> k = AdvSimd.
PolynomialMultiplyWideningLower(a.AsByte(),
AdvSimd.ExtractVector64(b.AsByte(), b.AsByte(), 4)).
AsByte(); // L = A0 * B4
// Add cross products
Vector128<byte> l = AdvSimd.Xor(e, f); // L = E + F
Vector128<byte> m = AdvSimd.Xor(g, h); // M = G + H
Vector128<byte> n = AdvSimd.Xor(i, j); // N = I + J
Vector128<byte> lmP0;
Vector128<byte> lmP1;
Vector128<byte> nkP0;
Vector128<byte> nkP1;
// Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL
// instructions.
if(AdvSimd.Arm64.IsSupported)
{
lmP0 = AdvSimd.Arm64.ZipLow(l.AsUInt64(), m.AsUInt64()).AsByte();
lmP1 = AdvSimd.Arm64.ZipHigh(l.AsUInt64(), m.AsUInt64()).AsByte();
nkP0 = AdvSimd.Arm64.ZipLow(n.AsUInt64(), k.AsUInt64()).AsByte();
nkP1 = AdvSimd.Arm64.ZipHigh(n.AsUInt64(), k.AsUInt64()).AsByte();
}
else
{
lmP0 = Vector128.Create(l.GetLower(), m.GetLower());
lmP1 = Vector128.Create(l.GetUpper(), m.GetUpper());
nkP0 = Vector128.Create(n.GetLower(), k.GetLower());
nkP1 = Vector128.Create(n.GetUpper(), k.GetUpper());
}
// t0 = (L) (P0 + P1) << 8
// t1 = (M) (P2 + P3) << 16
Vector128<byte> t0T1Tmp = AdvSimd.Xor(lmP0, lmP1);
Vector128<byte> t0T1H = AdvSimd.And(lmP1, k4832);
Vector128<byte> t0T1L = AdvSimd.Xor(t0T1Tmp, t0T1H);
// t2 = (N) (P4 + P5) << 24
// t3 = (K) (P6 + P7) << 32
Vector128<byte> t2T3Tmp = AdvSimd.Xor(nkP0, nkP1);
Vector128<byte> t2T3H = AdvSimd.And(nkP1, k1600);
Vector128<byte> t2T3L = AdvSimd.Xor(t2T3Tmp, t2T3H);
Vector128<byte> t1;
Vector128<byte> t0;
Vector128<byte> t3;
Vector128<byte> t2;
// De-interleave
if(AdvSimd.Arm64.IsSupported)
{
t0 = AdvSimd.Arm64.UnzipEven(t0T1L.AsUInt64(), t0T1H.AsUInt64()).AsByte();
t1 = AdvSimd.Arm64.UnzipOdd(t0T1L.AsUInt64(), t0T1H.AsUInt64()).AsByte();
t2 = AdvSimd.Arm64.UnzipEven(t2T3L.AsUInt64(), t2T3H.AsUInt64()).AsByte();
t3 = AdvSimd.Arm64.UnzipOdd(t2T3L.AsUInt64(), t2T3H.AsUInt64()).AsByte();
}
else
{
t1 = Vector128.Create(t0T1L.GetUpper(), t0T1H.GetUpper());
t0 = Vector128.Create(t0T1L.GetLower(), t0T1H.GetLower());
t3 = Vector128.Create(t2T3L.GetUpper(), t2T3H.GetUpper());
t2 = Vector128.Create(t2T3L.GetLower(), t2T3H.GetLower());
}
// Shift the cross products
Vector128<byte> t0Shift = AdvSimd.ExtractVector128(t0, t0, 15); // t0 << 8
Vector128<byte> t1Shift = AdvSimd.ExtractVector128(t1, t1, 14); // t1 << 16
Vector128<byte> t2Shift = AdvSimd.ExtractVector128(t2, t2, 13); // t2 << 24
Vector128<byte> t3Shift = AdvSimd.ExtractVector128(t3, t3, 12); // t3 << 32
// Accumulate the products
Vector128<byte> cross1 = AdvSimd.Xor(t0Shift, t1Shift);
Vector128<byte> cross2 = AdvSimd.Xor(t2Shift, t3Shift);
Vector128<byte> mix = AdvSimd.Xor(d, cross1);
Vector128<byte> r = AdvSimd.Xor(mix, cross2);
return r.AsUInt64();
return Aes.PolynomialMultiplyWideningLower(a, b);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static Vector128<ulong> mm_shuffle_epi8(Vector128<ulong> a, Vector128<ulong> b)
// Masks
Vector128<byte> k4832 = Vector128.Create(Vector64.Create(0x0000fffffffffffful),
Vector64.Create(0x00000000fffffffful)).AsByte();
Vector128<byte> k1600 = Vector128.Create(Vector64.Create(0x000000000000fffful),
Vector64.Create(0x0000000000000000ul)).AsByte();
// Do the multiplies, rotating with vext to get all combinations
Vector128<byte> d = AdvSimd.PolynomialMultiplyWideningLower(a.AsByte(), b.AsByte()).AsByte(); // D = A0 * B0
Vector128<byte> e = AdvSimd.
PolynomialMultiplyWideningLower(a.AsByte(),
AdvSimd.ExtractVector64(b.AsByte(), b.AsByte(), 1)).
AsByte(); // E = A0 * B1
Vector128<byte> f = AdvSimd.
PolynomialMultiplyWideningLower(AdvSimd.ExtractVector64(a.AsByte(), a.AsByte(), 1),
b.AsByte()).AsByte(); // F = A1 * B0
Vector128<byte> g = AdvSimd.
PolynomialMultiplyWideningLower(a.AsByte(),
AdvSimd.ExtractVector64(b.AsByte(), b.AsByte(), 2)).
AsByte(); // G = A0 * B2
Vector128<byte> h = AdvSimd.
PolynomialMultiplyWideningLower(AdvSimd.ExtractVector64(a.AsByte(), a.AsByte(), 2),
b.AsByte()).AsByte(); // H = A2 * B0
Vector128<byte> i = AdvSimd.
PolynomialMultiplyWideningLower(a.AsByte(),
AdvSimd.ExtractVector64(b.AsByte(), b.AsByte(), 3)).
AsByte(); // I = A0 * B3
Vector128<byte> j = AdvSimd.
PolynomialMultiplyWideningLower(AdvSimd.ExtractVector64(a.AsByte(), a.AsByte(), 3),
b.AsByte()).AsByte(); // J = A3 * B0
Vector128<byte> k = AdvSimd.
PolynomialMultiplyWideningLower(a.AsByte(),
AdvSimd.ExtractVector64(b.AsByte(), b.AsByte(), 4)).
AsByte(); // L = A0 * B4
// Add cross products
Vector128<byte> l = AdvSimd.Xor(e, f); // L = E + F
Vector128<byte> m = AdvSimd.Xor(g, h); // M = G + H
Vector128<byte> n = AdvSimd.Xor(i, j); // N = I + J
Vector128<byte> lmP0;
Vector128<byte> lmP1;
Vector128<byte> nkP0;
Vector128<byte> nkP1;
// Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL
// instructions.
if(AdvSimd.Arm64.IsSupported)
{
Vector128<byte> tbl = a.AsByte(); // input a
Vector128<byte> idx = b.AsByte(); // input b
Vector128<byte>
idxMasked = AdvSimd.And(idx, AdvSimd.DuplicateToVector128((byte)0x8F)); // avoid using meaningless bits
return AdvSimd.Arm64.VectorTableLookup(tbl, idxMasked).AsUInt64();
lmP0 = AdvSimd.Arm64.ZipLow(l.AsUInt64(), m.AsUInt64()).AsByte();
lmP1 = AdvSimd.Arm64.ZipHigh(l.AsUInt64(), m.AsUInt64()).AsByte();
nkP0 = AdvSimd.Arm64.ZipLow(n.AsUInt64(), k.AsUInt64()).AsByte();
nkP1 = AdvSimd.Arm64.ZipHigh(n.AsUInt64(), k.AsUInt64()).AsByte();
}
else
{
lmP0 = Vector128.Create(l.GetLower(), m.GetLower());
lmP1 = Vector128.Create(l.GetUpper(), m.GetUpper());
nkP0 = Vector128.Create(n.GetLower(), k.GetLower());
nkP1 = Vector128.Create(n.GetUpper(), k.GetUpper());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void Fold4(ref Vector128<ulong> qCRC0, ref Vector128<ulong> qCRC1, ref Vector128<ulong> qCRC2,
ref Vector128<ulong> qCRC3)
// t0 = (L) (P0 + P1) << 8
// t1 = (M) (P2 + P3) << 16
Vector128<byte> t0T1Tmp = AdvSimd.Xor(lmP0, lmP1);
Vector128<byte> t0T1H = AdvSimd.And(lmP1, k4832);
Vector128<byte> t0T1L = AdvSimd.Xor(t0T1Tmp, t0T1H);
// t2 = (N) (P4 + P5) << 24
// t3 = (K) (P6 + P7) << 32
Vector128<byte> t2T3Tmp = AdvSimd.Xor(nkP0, nkP1);
Vector128<byte> t2T3H = AdvSimd.And(nkP1, k1600);
Vector128<byte> t2T3L = AdvSimd.Xor(t2T3Tmp, t2T3H);
Vector128<byte> t1;
Vector128<byte> t0;
Vector128<byte> t3;
Vector128<byte> t2;
// De-interleave
if(AdvSimd.Arm64.IsSupported)
{
Vector128<ulong> qFold4 = Vector128.Create(0xc6e41596, 0x00000001, 0x54442bd4, 0x00000001).AsUInt64();
Vector128<ulong> xTmp0 = qCRC0;
Vector128<ulong> xTmp1 = qCRC1;
Vector128<ulong> xTmp2 = qCRC2;
Vector128<ulong> xTmp3 = qCRC3;
qCRC0 = vmull_p64(qCRC0.GetUpper(), qFold4.GetLower());
xTmp0 = vmull_p64(xTmp0.GetLower(), qFold4.GetUpper());
Vector128<uint> psCRC0 = qCRC0.AsUInt32();
Vector128<uint> psT0 = xTmp0.AsUInt32();
Vector128<uint> psRes0 = AdvSimd.Xor(psCRC0, psT0);
qCRC1 = vmull_p64(qCRC1.GetUpper(), qFold4.GetLower());
xTmp1 = vmull_p64(xTmp1.GetLower(), qFold4.GetUpper());
Vector128<uint> psCRC1 = qCRC1.AsUInt32();
Vector128<uint> psT1 = xTmp1.AsUInt32();
Vector128<uint> psRes1 = AdvSimd.Xor(psCRC1, psT1);
qCRC2 = vmull_p64(qCRC2.GetUpper(), qFold4.GetLower());
xTmp2 = vmull_p64(xTmp2.GetLower(), qFold4.GetUpper());
Vector128<uint> psCRC2 = qCRC2.AsUInt32();
Vector128<uint> psT2 = xTmp2.AsUInt32();
Vector128<uint> psRes2 = AdvSimd.Xor(psCRC2, psT2);
qCRC3 = vmull_p64(qCRC3.GetUpper(), qFold4.GetLower());
xTmp3 = vmull_p64(xTmp3.GetLower(), qFold4.GetUpper());
Vector128<uint> psCRC3 = qCRC3.AsUInt32();
Vector128<uint> psT3 = xTmp3.AsUInt32();
Vector128<uint> psRes3 = AdvSimd.Xor(psCRC3, psT3);
qCRC0 = psRes0.AsUInt64();
qCRC1 = psRes1.AsUInt64();
qCRC2 = psRes2.AsUInt64();
qCRC3 = psRes3.AsUInt64();
t0 = AdvSimd.Arm64.UnzipEven(t0T1L.AsUInt64(), t0T1H.AsUInt64()).AsByte();
t1 = AdvSimd.Arm64.UnzipOdd(t0T1L.AsUInt64(), t0T1H.AsUInt64()).AsByte();
t2 = AdvSimd.Arm64.UnzipEven(t2T3L.AsUInt64(), t2T3H.AsUInt64()).AsByte();
t3 = AdvSimd.Arm64.UnzipOdd(t2T3L.AsUInt64(), t2T3H.AsUInt64()).AsByte();
}
else
{
t1 = Vector128.Create(t0T1L.GetUpper(), t0T1H.GetUpper());
t0 = Vector128.Create(t0T1L.GetLower(), t0T1H.GetLower());
t3 = Vector128.Create(t2T3L.GetUpper(), t2T3H.GetUpper());
t2 = Vector128.Create(t2T3L.GetLower(), t2T3H.GetLower());
}
internal static uint Step(byte[] src, long len, uint initialCRC)
// Shift the cross products
Vector128<byte> t0Shift = AdvSimd.ExtractVector128(t0, t0, 15); // t0 << 8
Vector128<byte> t1Shift = AdvSimd.ExtractVector128(t1, t1, 14); // t1 << 16
Vector128<byte> t2Shift = AdvSimd.ExtractVector128(t2, t2, 13); // t2 << 24
Vector128<byte> t3Shift = AdvSimd.ExtractVector128(t3, t3, 12); // t3 << 32
// Accumulate the products
Vector128<byte> cross1 = AdvSimd.Xor(t0Shift, t1Shift);
Vector128<byte> cross2 = AdvSimd.Xor(t2Shift, t3Shift);
Vector128<byte> mix = AdvSimd.Xor(d, cross1);
Vector128<byte> r = AdvSimd.Xor(mix, cross2);
return r.AsUInt64();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static Vector128<ulong> mm_shuffle_epi8(Vector128<ulong> a, Vector128<ulong> b)
{
Vector128<byte> tbl = a.AsByte(); // input a
Vector128<byte> idx = b.AsByte(); // input b
Vector128<byte>
idxMasked = AdvSimd.And(idx, AdvSimd.DuplicateToVector128((byte)0x8F)); // avoid using meaningless bits
return AdvSimd.Arm64.VectorTableLookup(tbl, idxMasked).AsUInt64();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void Fold4(ref Vector128<ulong> qCRC0, ref Vector128<ulong> qCRC1, ref Vector128<ulong> qCRC2,
ref Vector128<ulong> qCRC3)
{
Vector128<ulong> qFold4 = Vector128.Create(0xc6e41596, 0x00000001, 0x54442bd4, 0x00000001).AsUInt64();
Vector128<ulong> xTmp0 = qCRC0;
Vector128<ulong> xTmp1 = qCRC1;
Vector128<ulong> xTmp2 = qCRC2;
Vector128<ulong> xTmp3 = qCRC3;
qCRC0 = vmull_p64(qCRC0.GetUpper(), qFold4.GetLower());
xTmp0 = vmull_p64(xTmp0.GetLower(), qFold4.GetUpper());
Vector128<uint> psCRC0 = qCRC0.AsUInt32();
Vector128<uint> psT0 = xTmp0.AsUInt32();
Vector128<uint> psRes0 = AdvSimd.Xor(psCRC0, psT0);
qCRC1 = vmull_p64(qCRC1.GetUpper(), qFold4.GetLower());
xTmp1 = vmull_p64(xTmp1.GetLower(), qFold4.GetUpper());
Vector128<uint> psCRC1 = qCRC1.AsUInt32();
Vector128<uint> psT1 = xTmp1.AsUInt32();
Vector128<uint> psRes1 = AdvSimd.Xor(psCRC1, psT1);
qCRC2 = vmull_p64(qCRC2.GetUpper(), qFold4.GetLower());
xTmp2 = vmull_p64(xTmp2.GetLower(), qFold4.GetUpper());
Vector128<uint> psCRC2 = qCRC2.AsUInt32();
Vector128<uint> psT2 = xTmp2.AsUInt32();
Vector128<uint> psRes2 = AdvSimd.Xor(psCRC2, psT2);
qCRC3 = vmull_p64(qCRC3.GetUpper(), qFold4.GetLower());
xTmp3 = vmull_p64(xTmp3.GetLower(), qFold4.GetUpper());
Vector128<uint> psCRC3 = qCRC3.AsUInt32();
Vector128<uint> psT3 = xTmp3.AsUInt32();
Vector128<uint> psRes3 = AdvSimd.Xor(psCRC3, psT3);
qCRC0 = psRes0.AsUInt64();
qCRC1 = psRes1.AsUInt64();
qCRC2 = psRes2.AsUInt64();
qCRC3 = psRes3.AsUInt64();
}
internal static uint Step(byte[] src, long len, uint initialCRC)
{
Vector128<ulong> qT0;
Vector128<ulong> qT1;
Vector128<ulong> qT2;
Vector128<ulong> qT3;
Vector128<ulong> qInitial = AdvSimd.Insert(Vector128<uint>.Zero, 0, initialCRC).AsUInt64();
Vector128<ulong> qCRC0 = AdvSimd.Insert(Vector128<uint>.Zero, 0, 0x9db42487).AsUInt64();
Vector128<ulong> qCRC1 = Vector128<ulong>.Zero;
Vector128<ulong> qCRC2 = Vector128<ulong>.Zero;
Vector128<ulong> qCRC3 = Vector128<ulong>.Zero;
int bufPos = 0;
bool first = true;
/* fold 512 to 32 step variable declarations for ISO-C90 compat. */
Vector128<uint> qMask = Vector128.Create(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000);
Vector128<uint> qMask2 = Vector128.Create(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
uint crc;
Vector128<ulong> xTmp0;
Vector128<ulong> xTmp1;
Vector128<ulong> xTmp2;
Vector128<ulong> crcFold;
while((len -= 64) >= 0)
{
Vector128<ulong> qT0;
Vector128<ulong> qT1;
Vector128<ulong> qT2;
Vector128<ulong> qT3;
Vector128<ulong> qInitial = AdvSimd.Insert(Vector128<uint>.Zero, 0, initialCRC).AsUInt64();
Vector128<ulong> qCRC0 = AdvSimd.Insert(Vector128<uint>.Zero, 0, 0x9db42487).AsUInt64();
Vector128<ulong> qCRC1 = Vector128<ulong>.Zero;
Vector128<ulong> qCRC2 = Vector128<ulong>.Zero;
Vector128<ulong> qCRC3 = Vector128<ulong>.Zero;
int bufPos = 0;
qT0 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12)).
AsUInt64();
bool first = true;
bufPos += 16;
/* fold 512 to 32 step variable declarations for ISO-C90 compat. */
Vector128<uint> qMask = Vector128.Create(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000);
Vector128<uint> qMask2 = Vector128.Create(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
qT1 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12)).
AsUInt64();
uint crc;
Vector128<ulong> xTmp0;
Vector128<ulong> xTmp1;
Vector128<ulong> xTmp2;
Vector128<ulong> crcFold;
bufPos += 16;
while((len -= 64) >= 0)
qT2 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12)).
AsUInt64();
bufPos += 16;
qT3 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12)).
AsUInt64();
bufPos += 16;
if(first)
{
qT0 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12)).
AsUInt64();
first = false;
bufPos += 16;
qT1 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12)).
AsUInt64();
bufPos += 16;
qT2 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12)).
AsUInt64();
bufPos += 16;
qT3 = Vector128.Create(BitConverter.ToUInt32(src, bufPos), BitConverter.ToUInt32(src, bufPos + 4),
BitConverter.ToUInt32(src, bufPos + 8), BitConverter.ToUInt32(src, bufPos + 12)).
AsUInt64();
bufPos += 16;
if(first)
{
first = false;
qT0 = AdvSimd.Xor(qT0.AsUInt32(), qInitial.AsUInt32()).AsUInt64();
}
Fold4(ref qCRC0, ref qCRC1, ref qCRC2, ref qCRC3);
qCRC0 = AdvSimd.Xor(qCRC0.AsUInt32(), qT0.AsUInt32()).AsUInt64();
qCRC1 = AdvSimd.Xor(qCRC1.AsUInt32(), qT1.AsUInt32()).AsUInt64();
qCRC2 = AdvSimd.Xor(qCRC2.AsUInt32(), qT2.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qT3.AsUInt32()).AsUInt64();
qT0 = AdvSimd.Xor(qT0.AsUInt32(), qInitial.AsUInt32()).AsUInt64();
}
/* fold 512 to 32 */
Fold4(ref qCRC0, ref qCRC1, ref qCRC2, ref qCRC3);
/*
* k1
*/
crcFold = Vector128.Create(_crcK[0], _crcK[1], _crcK[2], _crcK[3]).AsUInt64();
xTmp0 = vmull_p64(qCRC0.GetLower(), crcFold.GetUpper());
qCRC0 = vmull_p64(qCRC0.GetUpper(), crcFold.GetLower());
qCRC1 = AdvSimd.Xor(qCRC1.AsUInt32(), xTmp0.AsUInt32()).AsUInt64();
qCRC1 = AdvSimd.Xor(qCRC1.AsUInt32(), qCRC0.AsUInt32()).AsUInt64();
xTmp1 = vmull_p64(qCRC1.GetLower(), crcFold.GetUpper());
qCRC1 = vmull_p64(qCRC1.GetUpper(), crcFold.GetLower());
qCRC2 = AdvSimd.Xor(qCRC2.AsUInt32(), xTmp1.AsUInt32()).AsUInt64();
qCRC2 = AdvSimd.Xor(qCRC2.AsUInt32(), qCRC1.AsUInt32()).AsUInt64();
xTmp2 = vmull_p64(qCRC2.GetLower(), crcFold.GetUpper());
qCRC2 = vmull_p64(qCRC2.GetUpper(), crcFold.GetLower());
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), xTmp2.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC2.AsUInt32()).AsUInt64();
/*
* k5
*/
crcFold = Vector128.Create(_crcK[4], _crcK[5], _crcK[6], _crcK[7]).AsUInt64();
qCRC0 = qCRC3;
qCRC3 = vmull_p64(qCRC3.GetLower(), crcFold.GetLower());
Vector128<byte> qCRC0B = qCRC0.AsByte();
qCRC0 = Vector128.Create(AdvSimd.Extract(qCRC0B, 8), AdvSimd.Extract(qCRC0B, 9),
AdvSimd.Extract(qCRC0B, 10), AdvSimd.Extract(qCRC0B, 11),
AdvSimd.Extract(qCRC0B, 12), AdvSimd.Extract(qCRC0B, 13),
AdvSimd.Extract(qCRC0B, 14), AdvSimd.Extract(qCRC0B, 15), 0, 0, 0, 0, 0, 0, 0, 0).
AsUInt64();
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC0.AsUInt32()).AsUInt64();
qCRC0 = qCRC3;
Vector128<byte> qCRC3B = qCRC3.AsByte();
qCRC3 = Vector128.Create(0, 0, 0, 0, AdvSimd.Extract(qCRC3B, 0), AdvSimd.Extract(qCRC3B, 1),
AdvSimd.Extract(qCRC3B, 2), AdvSimd.Extract(qCRC3B, 3), AdvSimd.Extract(qCRC3B, 4),
AdvSimd.Extract(qCRC3B, 5), AdvSimd.Extract(qCRC3B, 6), AdvSimd.Extract(qCRC3B, 7),
AdvSimd.Extract(qCRC3B, 8), AdvSimd.Extract(qCRC3B, 9),
AdvSimd.Extract(qCRC3B, 10), AdvSimd.Extract(qCRC3B, 11)).AsUInt64();
qCRC3 = vmull_p64(qCRC3.GetLower(), crcFold.GetUpper());
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC0.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.And(qCRC3.AsUInt32(), qMask2.AsUInt32()).AsUInt64();
/*
* k7
*/
qCRC1 = qCRC3;
qCRC2 = qCRC3;
crcFold = Vector128.Create(_crcK[8], _crcK[9], _crcK[10], _crcK[11]).AsUInt64();
qCRC3 = vmull_p64(qCRC3.GetLower(), crcFold.GetLower());
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC2.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.And(qCRC3.AsUInt32(), qMask.AsUInt32()).AsUInt64();
qCRC2 = qCRC3;
qCRC3 = vmull_p64(qCRC3.GetLower(), crcFold.GetUpper());
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC2.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC1.AsUInt32()).AsUInt64();
/*
* could just as well write q_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 ~AdvSimd.Extract(qCRC3.AsUInt32(), 2);
qCRC0 = AdvSimd.Xor(qCRC0.AsUInt32(), qT0.AsUInt32()).AsUInt64();
qCRC1 = AdvSimd.Xor(qCRC1.AsUInt32(), qT1.AsUInt32()).AsUInt64();
qCRC2 = AdvSimd.Xor(qCRC2.AsUInt32(), qT2.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qT3.AsUInt32()).AsUInt64();
}
/* fold 512 to 32 */
/*
* k1
*/
crcFold = Vector128.Create(_crcK[0], _crcK[1], _crcK[2], _crcK[3]).AsUInt64();
xTmp0 = vmull_p64(qCRC0.GetLower(), crcFold.GetUpper());
qCRC0 = vmull_p64(qCRC0.GetUpper(), crcFold.GetLower());
qCRC1 = AdvSimd.Xor(qCRC1.AsUInt32(), xTmp0.AsUInt32()).AsUInt64();
qCRC1 = AdvSimd.Xor(qCRC1.AsUInt32(), qCRC0.AsUInt32()).AsUInt64();
xTmp1 = vmull_p64(qCRC1.GetLower(), crcFold.GetUpper());
qCRC1 = vmull_p64(qCRC1.GetUpper(), crcFold.GetLower());
qCRC2 = AdvSimd.Xor(qCRC2.AsUInt32(), xTmp1.AsUInt32()).AsUInt64();
qCRC2 = AdvSimd.Xor(qCRC2.AsUInt32(), qCRC1.AsUInt32()).AsUInt64();
xTmp2 = vmull_p64(qCRC2.GetLower(), crcFold.GetUpper());
qCRC2 = vmull_p64(qCRC2.GetUpper(), crcFold.GetLower());
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), xTmp2.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC2.AsUInt32()).AsUInt64();
/*
* k5
*/
crcFold = Vector128.Create(_crcK[4], _crcK[5], _crcK[6], _crcK[7]).AsUInt64();
qCRC0 = qCRC3;
qCRC3 = vmull_p64(qCRC3.GetLower(), crcFold.GetLower());
Vector128<byte> qCRC0B = qCRC0.AsByte();
qCRC0 = Vector128.Create(AdvSimd.Extract(qCRC0B, 8), AdvSimd.Extract(qCRC0B, 9), AdvSimd.Extract(qCRC0B, 10),
AdvSimd.Extract(qCRC0B, 11), AdvSimd.Extract(qCRC0B, 12), AdvSimd.Extract(qCRC0B, 13),
AdvSimd.Extract(qCRC0B, 14), AdvSimd.Extract(qCRC0B, 15), 0, 0, 0, 0, 0, 0, 0, 0).
AsUInt64();
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC0.AsUInt32()).AsUInt64();
qCRC0 = qCRC3;
Vector128<byte> qCRC3B = qCRC3.AsByte();
qCRC3 = Vector128.Create(0, 0, 0, 0, AdvSimd.Extract(qCRC3B, 0), AdvSimd.Extract(qCRC3B, 1),
AdvSimd.Extract(qCRC3B, 2), AdvSimd.Extract(qCRC3B, 3), AdvSimd.Extract(qCRC3B, 4),
AdvSimd.Extract(qCRC3B, 5), AdvSimd.Extract(qCRC3B, 6), AdvSimd.Extract(qCRC3B, 7),
AdvSimd.Extract(qCRC3B, 8), AdvSimd.Extract(qCRC3B, 9), AdvSimd.Extract(qCRC3B, 10),
AdvSimd.Extract(qCRC3B, 11)).AsUInt64();
qCRC3 = vmull_p64(qCRC3.GetLower(), crcFold.GetUpper());
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC0.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.And(qCRC3.AsUInt32(), qMask2.AsUInt32()).AsUInt64();
/*
* k7
*/
qCRC1 = qCRC3;
qCRC2 = qCRC3;
crcFold = Vector128.Create(_crcK[8], _crcK[9], _crcK[10], _crcK[11]).AsUInt64();
qCRC3 = vmull_p64(qCRC3.GetLower(), crcFold.GetLower());
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC2.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.And(qCRC3.AsUInt32(), qMask.AsUInt32()).AsUInt64();
qCRC2 = qCRC3;
qCRC3 = vmull_p64(qCRC3.GetLower(), crcFold.GetUpper());
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC2.AsUInt32()).AsUInt64();
qCRC3 = AdvSimd.Xor(qCRC3.AsUInt32(), qCRC1.AsUInt32()).AsUInt64();
/*
* could just as well write q_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 ~AdvSimd.Extract(qCRC3.AsUInt32(), 2);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -26,86 +26,85 @@ using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
namespace Aaru6.Checksums.CRC64
namespace Aaru6.Checksums.CRC64;
internal static class Clmul
{
internal static class Clmul
static readonly byte[] _shuffleMasks =
{
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;
Vector128<byte> 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)
{
int bufPos = 16;
const ulong k1 = 0xe05dd497ca393ae4;
const ulong k2 = 0xdabe95afc7875f40;
const ulong mu = 0x9c3e466c172963d5;
const ulong pol = 0x92d8af2baf0e1e85;
Vector128<ulong> foldConstants1 = Vector128.Create(k1, k2);
Vector128<ulong> foldConstants2 = Vector128.Create(mu, pol);
Vector128<ulong> 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)
{
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
};
accumulator =
Fold(Sse2.Xor(Vector128.Create(BitConverter.ToUInt64(data, bufPos), BitConverter.ToUInt64(data, bufPos + 8)), accumulator),
foldConstants1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void ShiftRight128(Vector128<ulong> initial, uint n, out Vector128<ulong> outLeft,
out Vector128<ulong> outRight)
{
uint maskPos = 16 - n;
Vector128<byte> 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)
{
int bufPos = 16;
const ulong k1 = 0xe05dd497ca393ae4;
const ulong k2 = 0xdabe95afc7875f40;
const ulong mu = 0x9c3e466c172963d5;
const ulong pol = 0x92d8af2baf0e1e85;
Vector128<ulong> foldConstants1 = Vector128.Create(k1, k2);
Vector128<ulong> foldConstants2 = Vector128.Create(mu, pol);
Vector128<ulong> 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));
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));
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +1,45 @@
using System.Runtime.InteropServices;
namespace Aaru6.Checksums
namespace Aaru6.Checksums;
public static class Native
{
public static class Native
static bool _checked;
static bool _supported;
public static bool ForceManaged { get; set; }
public static bool IsSupported
{
static bool _checked;
static bool _supported;
public static bool ForceManaged { get; set; }
public static bool IsSupported
get
{
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;
if(ForceManaged)
return false;
if(_checked)
return _supported;
}
}
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern ulong get_acn_version();
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();
}

View File

@@ -44,280 +44,331 @@ using System.Runtime.CompilerServices;
using System.Text;
using Aaru.CommonTypes.Interfaces;
namespace Aaru6.Checksums
namespace Aaru6.Checksums;
/// <inheritdoc />
/// <summary>Implements the SpamSum fuzzy hashing algorithm.</summary>
public sealed class SpamSumContext : IChecksum
{
/// <inheritdoc />
/// <summary>Implements the SpamSum fuzzy hashing algorithm.</summary>
public sealed class SpamSumContext : IChecksum
const uint ROLLING_WINDOW = 7;
const uint MIN_BLOCKSIZE = 3;
const uint HASH_PRIME = 0x01000193;
const uint HASH_INIT = 0x28021967;
const uint NUM_BLOCKHASHES = 31;
const uint SPAMSUM_LENGTH = 64;
const uint FUZZY_MAX_RESULT = (2 * SPAMSUM_LENGTH) + 20;
//"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
readonly byte[] _b64 =
{
const uint ROLLING_WINDOW = 7;
const uint MIN_BLOCKSIZE = 3;
const uint HASH_PRIME = 0x01000193;
const uint HASH_INIT = 0x28021967;
const uint NUM_BLOCKHASHES = 31;
const uint SPAMSUM_LENGTH = 64;
const uint FUZZY_MAX_RESULT = (2 * SPAMSUM_LENGTH) + 20;
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
};
//"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
readonly byte[] _b64 =
FuzzyState _self;
/// <summary>Initializes the SpamSum structures</summary>
public SpamSumContext()
{
_self = new FuzzyState
{
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
Bh = new BlockhashContext[NUM_BLOCKHASHES]
};
FuzzyState _self;
for(int i = 0; i < NUM_BLOCKHASHES; i++)
_self.Bh[i].Digest = new byte[SPAMSUM_LENGTH];
/// <summary>Initializes the SpamSum structures</summary>
public SpamSumContext()
_self.Bhstart = 0;
_self.Bhend = 1;
_self.Bh[0].H = HASH_INIT;
_self.Bh[0].Halfh = HASH_INIT;
_self.Bh[0].Digest[0] = 0;
_self.Bh[0].Halfdigest = 0;
_self.Bh[0].Dlen = 0;
_self.TotalSize = 0;
roll_init();
}
/// <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)
{
_self.TotalSize += len;
for(int i = 0; i < len; i++)
fuzzy_engine_step(data[i]);
}
/// <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() => throw new NotImplementedException("SpamSum does not have a binary representation.");
/// <inheritdoc />
/// <summary>Returns a base64 representation of the hash value.</summary>
public string End()
{
FuzzyDigest(out byte[] result);
return CToString(result);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void roll_init() => _self.Roll = new RollState
{
Window = new byte[ROLLING_WINDOW]
};
/*
* a rolling hash, based on the Adler checksum. By using a rolling hash
* we can perform auto resynchronisation after inserts/deletes
* internally, h1 is the sum of the bytes in the window and h2
* is the sum of the bytes times the index
* h3 is a shift/xor based rolling hash, and is mostly needed to ensure that
* we can cope with large blocksize values
*/
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void roll_hash(byte c)
{
_self.Roll.H2 -= _self.Roll.H1;
_self.Roll.H2 += ROLLING_WINDOW * c;
_self.Roll.H1 += c;
_self.Roll.H1 -= _self.Roll.Window[_self.Roll.N % ROLLING_WINDOW];
_self.Roll.Window[_self.Roll.N % ROLLING_WINDOW] = c;
_self.Roll.N++;
/* The original spamsum AND'ed this value with 0xFFFFFFFF which
* in theory should have no effect. This AND has been removed
* for performance (jk) */
_self.Roll.H3 <<= 5;
_self.Roll.H3 ^= c;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
uint roll_sum() => _self.Roll.H1 + _self.Roll.H2 + _self.Roll.H3;
/* A simple non-rolling hash, based on the FNV hash. */
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static uint sum_hash(byte c, uint h) => (h * HASH_PRIME) ^ c;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static uint SSDEEP_BS(uint index) => MIN_BLOCKSIZE << (int)index;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void fuzzy_try_fork_blockhash()
{
if(_self.Bhend >= NUM_BLOCKHASHES)
return;
if(_self.Bhend == 0) // assert
throw new Exception("Assertion failed");
uint obh = _self.Bhend - 1;
uint nbh = _self.Bhend;
_self.Bh[nbh].H = _self.Bh[obh].H;
_self.Bh[nbh].Halfh = _self.Bh[obh].Halfh;
_self.Bh[nbh].Digest[0] = 0;
_self.Bh[nbh].Halfdigest = 0;
_self.Bh[nbh].Dlen = 0;
++_self.Bhend;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void fuzzy_try_reduce_blockhash()
{
if(_self.Bhstart >= _self.Bhend)
throw new Exception("Assertion failed");
if(_self.Bhend - _self.Bhstart < 2)
/* Need at least two working hashes. */
return;
if((ulong)SSDEEP_BS(_self.Bhstart) * SPAMSUM_LENGTH >= _self.TotalSize)
/* Initial blocksize estimate would select this or a smaller
* blocksize. */
return;
if(_self.Bh[_self.Bhstart + 1].Dlen < SPAMSUM_LENGTH / 2)
/* Estimate adjustment would select this blocksize. */
return;
/* At this point we are clearly no longer interested in the
* start_blocksize. Get rid of it. */
++_self.Bhstart;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void fuzzy_engine_step(byte c)
{
uint i;
/* At each character we update the rolling hash and the normal hashes.
* When the rolling hash hits a reset value then we emit a normal hash
* as a element of the signature and reset the normal hash. */
roll_hash(c);
ulong h = roll_sum();
for(i = _self.Bhstart; i < _self.Bhend; ++i)
{
_self = new FuzzyState
_self.Bh[i].H = sum_hash(c, _self.Bh[i].H);
_self.Bh[i].Halfh = sum_hash(c, _self.Bh[i].Halfh);
}
for(i = _self.Bhstart; i < _self.Bhend; ++i)
{
/* With growing blocksize almost no runs fail the next test. */
if(h % SSDEEP_BS(i) != SSDEEP_BS(i) - 1)
/* Once this condition is false for one bs, it is
* automatically false for all further bs. I.e. if
* h === -1 (mod 2*bs) then h === -1 (mod bs). */
break;
/* We have hit a reset point. We now emit hashes which are
* based on all characters in the piece of the message between
* the last reset point and this one */
if(0 == _self.Bh[i].Dlen)
fuzzy_try_fork_blockhash();
_self.Bh[i].Digest[_self.Bh[i].Dlen] = _b64[_self.Bh[i].H % 64];
_self.Bh[i].Halfdigest = _b64[_self.Bh[i].Halfh % 64];
if(_self.Bh[i].Dlen < SPAMSUM_LENGTH - 1)
{
Bh = new BlockhashContext[NUM_BLOCKHASHES]
};
/* We can have a problem with the tail overflowing. The
* easiest way to cope with this is to only reset the
* normal hash if we have room for more characters in
* our signature. This has the effect of combining the
* last few pieces of the message into a single piece
* */
_self.Bh[i].Digest[++_self.Bh[i].Dlen] = 0;
_self.Bh[i].H = HASH_INIT;
for(int i = 0; i < NUM_BLOCKHASHES; i++)
_self.Bh[i].Digest = new byte[SPAMSUM_LENGTH];
if(_self.Bh[i].Dlen >= SPAMSUM_LENGTH / 2)
continue;
_self.Bhstart = 0;
_self.Bhend = 1;
_self.Bh[0].H = HASH_INIT;
_self.Bh[0].Halfh = HASH_INIT;
_self.Bh[0].Digest[0] = 0;
_self.Bh[0].Halfdigest = 0;
_self.Bh[0].Dlen = 0;
_self.TotalSize = 0;
roll_init();
}
/// <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)
{
_self.TotalSize += len;
for(int i = 0; i < len; i++)
fuzzy_engine_step(data[i]);
}
/// <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() => throw new NotImplementedException("SpamSum does not have a binary representation.");
/// <inheritdoc />
/// <summary>Returns a base64 representation of the hash value.</summary>
public string End()
{
FuzzyDigest(out byte[] result);
return CToString(result);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void roll_init() => _self.Roll = new RollState
{
Window = new byte[ROLLING_WINDOW]
};
/*
* a rolling hash, based on the Adler checksum. By using a rolling hash
* we can perform auto resynchronisation after inserts/deletes
* internally, h1 is the sum of the bytes in the window and h2
* is the sum of the bytes times the index
* h3 is a shift/xor based rolling hash, and is mostly needed to ensure that
* we can cope with large blocksize values
*/
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void roll_hash(byte c)
{
_self.Roll.H2 -= _self.Roll.H1;
_self.Roll.H2 += ROLLING_WINDOW * c;
_self.Roll.H1 += c;
_self.Roll.H1 -= _self.Roll.Window[_self.Roll.N % ROLLING_WINDOW];
_self.Roll.Window[_self.Roll.N % ROLLING_WINDOW] = c;
_self.Roll.N++;
/* The original spamsum AND'ed this value with 0xFFFFFFFF which
* in theory should have no effect. This AND has been removed
* for performance (jk) */
_self.Roll.H3 <<= 5;
_self.Roll.H3 ^= c;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
uint roll_sum() => _self.Roll.H1 + _self.Roll.H2 + _self.Roll.H3;
/* A simple non-rolling hash, based on the FNV hash. */
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static uint sum_hash(byte c, uint h) => (h * HASH_PRIME) ^ c;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static uint SSDEEP_BS(uint index) => MIN_BLOCKSIZE << (int)index;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void fuzzy_try_fork_blockhash()
{
if(_self.Bhend >= NUM_BLOCKHASHES)
return;
if(_self.Bhend == 0) // assert
throw new Exception("Assertion failed");
uint obh = _self.Bhend - 1;
uint nbh = _self.Bhend;
_self.Bh[nbh].H = _self.Bh[obh].H;
_self.Bh[nbh].Halfh = _self.Bh[obh].Halfh;
_self.Bh[nbh].Digest[0] = 0;
_self.Bh[nbh].Halfdigest = 0;
_self.Bh[nbh].Dlen = 0;
++_self.Bhend;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void fuzzy_try_reduce_blockhash()
{
if(_self.Bhstart >= _self.Bhend)
throw new Exception("Assertion failed");
if(_self.Bhend - _self.Bhstart < 2)
/* Need at least two working hashes. */
return;
if((ulong)SSDEEP_BS(_self.Bhstart) * SPAMSUM_LENGTH >= _self.TotalSize)
/* Initial blocksize estimate would select this or a smaller
* blocksize. */
return;
if(_self.Bh[_self.Bhstart + 1].Dlen < SPAMSUM_LENGTH / 2)
/* Estimate adjustment would select this blocksize. */
return;
/* At this point we are clearly no longer interested in the
* start_blocksize. Get rid of it. */
++_self.Bhstart;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void fuzzy_engine_step(byte c)
{
uint i;
/* At each character we update the rolling hash and the normal hashes.
* When the rolling hash hits a reset value then we emit a normal hash
* as a element of the signature and reset the normal hash. */
roll_hash(c);
ulong h = roll_sum();
for(i = _self.Bhstart; i < _self.Bhend; ++i)
{
_self.Bh[i].H = sum_hash(c, _self.Bh[i].H);
_self.Bh[i].Halfh = sum_hash(c, _self.Bh[i].Halfh);
}
for(i = _self.Bhstart; i < _self.Bhend; ++i)
{
/* With growing blocksize almost no runs fail the next test. */
if(h % SSDEEP_BS(i) != SSDEEP_BS(i) - 1)
/* Once this condition is false for one bs, it is
* automatically false for all further bs. I.e. if
* h === -1 (mod 2*bs) then h === -1 (mod bs). */
break;
/* We have hit a reset point. We now emit hashes which are
* based on all characters in the piece of the message between
* the last reset point and this one */
if(0 == _self.Bh[i].Dlen)
fuzzy_try_fork_blockhash();
_self.Bh[i].Digest[_self.Bh[i].Dlen] = _b64[_self.Bh[i].H % 64];
_self.Bh[i].Halfdigest = _b64[_self.Bh[i].Halfh % 64];
if(_self.Bh[i].Dlen < SPAMSUM_LENGTH - 1)
{
/* We can have a problem with the tail overflowing. The
* easiest way to cope with this is to only reset the
* normal hash if we have room for more characters in
* our signature. This has the effect of combining the
* last few pieces of the message into a single piece
* */
_self.Bh[i].Digest[++_self.Bh[i].Dlen] = 0;
_self.Bh[i].H = HASH_INIT;
if(_self.Bh[i].Dlen >= SPAMSUM_LENGTH / 2)
continue;
_self.Bh[i].Halfh = HASH_INIT;
_self.Bh[i].Halfdigest = 0;
}
else
fuzzy_try_reduce_blockhash();
_self.Bh[i].Halfh = HASH_INIT;
_self.Bh[i].Halfdigest = 0;
}
else
fuzzy_try_reduce_blockhash();
}
}
// CLAUNIA: Flags seems to never be used in ssdeep, so I just removed it for code simplicity
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void FuzzyDigest(out byte[] result)
// CLAUNIA: Flags seems to never be used in ssdeep, so I just removed it for code simplicity
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void FuzzyDigest(out byte[] result)
{
var sb = new StringBuilder();
uint bi = _self.Bhstart;
uint h = roll_sum();
int remain = (int)(FUZZY_MAX_RESULT - 1); /* Exclude terminating '\0'. */
result = new byte[FUZZY_MAX_RESULT];
/* Verify that our elimination was not overeager. */
if(!(bi == 0 || (ulong)SSDEEP_BS(bi) / 2 * SPAMSUM_LENGTH < _self.TotalSize))
throw new Exception("Assertion failed");
int resultOff;
/* Initial blocksize guess. */
while((ulong)SSDEEP_BS(bi) * SPAMSUM_LENGTH < _self.TotalSize)
{
var sb = new StringBuilder();
uint bi = _self.Bhstart;
uint h = roll_sum();
int remain = (int)(FUZZY_MAX_RESULT - 1); /* Exclude terminating '\0'. */
result = new byte[FUZZY_MAX_RESULT];
++bi;
/* Verify that our elimination was not overeager. */
if(!(bi == 0 || (ulong)SSDEEP_BS(bi) / 2 * SPAMSUM_LENGTH < _self.TotalSize))
throw new Exception("Assertion failed");
int resultOff;
/* Initial blocksize guess. */
while((ulong)SSDEEP_BS(bi) * SPAMSUM_LENGTH < _self.TotalSize)
{
++bi;
if(bi >= NUM_BLOCKHASHES)
throw new OverflowException("The input exceeds data types.");
}
/* Adapt blocksize guess to actual digest length. */
while(bi >= _self.Bhend)
--bi;
while(bi > _self.Bhstart &&
_self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2)
--bi;
if(bi > 0 &&
_self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2)
throw new Exception("Assertion failed");
sb.AppendFormat("{0}:", SSDEEP_BS(bi));
int i = Encoding.ASCII.GetBytes(sb.ToString()).Length;
if(i <= 0)
/* Maybe snprintf has set errno here? */
if(bi >= NUM_BLOCKHASHES)
throw new OverflowException("The input exceeds data types.");
}
if(i >= remain)
/* Adapt blocksize guess to actual digest length. */
while(bi >= _self.Bhend)
--bi;
while(bi > _self.Bhstart &&
_self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2)
--bi;
if(bi > 0 &&
_self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2)
throw new Exception("Assertion failed");
sb.AppendFormat("{0}:", SSDEEP_BS(bi));
int i = Encoding.ASCII.GetBytes(sb.ToString()).Length;
if(i <= 0)
/* Maybe snprintf has set errno here? */
throw new OverflowException("The input exceeds data types.");
if(i >= remain)
throw new Exception("Assertion failed");
remain -= i;
Array.Copy(Encoding.ASCII.GetBytes(sb.ToString()), 0, result, 0, i);
resultOff = i;
i = (int)_self.Bh[bi].Dlen;
if(i > remain)
throw new Exception("Assertion failed");
Array.Copy(_self.Bh[bi].Digest, 0, result, resultOff, i);
resultOff += i;
remain -= i;
if(h != 0)
{
if(remain <= 0)
throw new Exception("Assertion failed");
remain -= i;
result[resultOff] = _b64[_self.Bh[bi].H % 64];
Array.Copy(Encoding.ASCII.GetBytes(sb.ToString()), 0, result, 0, i);
if(i < 3 ||
result[resultOff] != result[resultOff - 1] ||
result[resultOff] != result[resultOff - 2] ||
result[resultOff] != result[resultOff - 3])
{
++resultOff;
--remain;
}
}
else if(_self.Bh[bi].Digest[i] != 0)
{
if(remain <= 0)
throw new Exception("Assertion failed");
resultOff = i;
result[resultOff] = _self.Bh[bi].Digest[i];
if(i < 3 ||
result[resultOff] != result[resultOff - 1] ||
result[resultOff] != result[resultOff - 2] ||
result[resultOff] != result[resultOff - 3])
{
++resultOff;
--remain;
}
}
if(remain <= 0)
throw new Exception("Assertion failed");
result[resultOff++] = 0x3A; // ':'
--remain;
if(bi < _self.Bhend - 1)
{
++bi;
i = (int)_self.Bh[bi].Dlen;
if(i > remain)
@@ -332,7 +383,8 @@ namespace Aaru6.Checksums
if(remain <= 0)
throw new Exception("Assertion failed");
result[resultOff] = _b64[_self.Bh[bi].H % 64];
h = _self.Bh[bi].Halfh;
result[resultOff] = _b64[h % 64];
if(i < 3 ||
result[resultOff] != result[resultOff - 1] ||
@@ -343,48 +395,16 @@ namespace Aaru6.Checksums
--remain;
}
}
else if(_self.Bh[bi].Digest[i] != 0)
else
{
if(remain <= 0)
throw new Exception("Assertion failed");
i = _self.Bh[bi].Halfdigest;
result[resultOff] = _self.Bh[bi].Digest[i];
if(i < 3 ||
result[resultOff] != result[resultOff - 1] ||
result[resultOff] != result[resultOff - 2] ||
result[resultOff] != result[resultOff - 3])
{
++resultOff;
--remain;
}
}
if(remain <= 0)
throw new Exception("Assertion failed");
result[resultOff++] = 0x3A; // ':'
--remain;
if(bi < _self.Bhend - 1)
{
++bi;
i = (int)_self.Bh[bi].Dlen;
if(i > remain)
throw new Exception("Assertion failed");
Array.Copy(_self.Bh[bi].Digest, 0, result, resultOff, i);
resultOff += i;
remain -= i;
if(h != 0)
if(i != 0)
{
if(remain <= 0)
throw new Exception("Assertion failed");
h = _self.Bh[bi].Halfh;
result[resultOff] = _b64[h % 64];
result[resultOff] = (byte)i;
if(i < 3 ||
result[resultOff] != result[resultOff - 1] ||
@@ -395,133 +415,112 @@ namespace Aaru6.Checksums
--remain;
}
}
else
{
i = _self.Bh[bi].Halfdigest;
if(i != 0)
{
if(remain <= 0)
throw new Exception("Assertion failed");
result[resultOff] = (byte)i;
if(i < 3 ||
result[resultOff] != result[resultOff - 1] ||
result[resultOff] != result[resultOff - 2] ||
result[resultOff] != result[resultOff - 3])
{
++resultOff;
--remain;
}
}
}
}
else if(h != 0)
{
if(_self.Bh[bi].Dlen != 0)
throw new Exception("Assertion failed");
if(remain <= 0)
throw new Exception("Assertion failed");
result[resultOff++] = _b64[_self.Bh[bi].H % 64];
/* No need to bother with FUZZY_FLAG_ELIMSEQ, because this
* digest has length 1. */
--remain;
}
result[resultOff] = 0;
}
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
public static byte[] File(string filename) =>
throw new NotImplementedException("SpamSum does not have a binary representation.");
/// <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) =>
throw new NotImplementedException("Not yet implemented.");
/// <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">null</param>
/// <returns>Base64 representation of SpamSum $blocksize:$hash:$hash</returns>
public static string Data(byte[] data, uint len, out byte[] hash)
else if(h != 0)
{
var fuzzyContext = new SpamSumContext();
if(_self.Bh[bi].Dlen != 0)
throw new Exception("Assertion failed");
fuzzyContext.Update(data, len);
if(remain <= 0)
throw new Exception("Assertion failed");
hash = null;
return fuzzyContext.End();
result[resultOff++] = _b64[_self.Bh[bi].H % 64];
/* No need to bother with FUZZY_FLAG_ELIMSEQ, because this
* digest has length 1. */
--remain;
}
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="hash">null</param>
/// <returns>Base64 representation of SpamSum $blocksize:$hash:$hash</returns>
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
result[resultOff] = 0;
}
// Converts an ASCII null-terminated string to .NET string
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static string CToString(byte[] cString)
/// <summary>Gets the hash of a file</summary>
/// <param name="filename">File path.</param>
public static byte[] File(string filename) =>
throw new NotImplementedException("SpamSum does not have a binary representation.");
/// <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) =>
throw new NotImplementedException("Not yet implemented.");
/// <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">null</param>
/// <returns>Base64 representation of SpamSum $blocksize:$hash:$hash</returns>
public static string Data(byte[] data, uint len, out byte[] hash)
{
var fuzzyContext = new SpamSumContext();
fuzzyContext.Update(data, len);
hash = null;
return fuzzyContext.End();
}
/// <summary>Gets the hash of the specified data buffer.</summary>
/// <param name="data">Data buffer.</param>
/// <param name="hash">null</param>
/// <returns>Base64 representation of SpamSum $blocksize:$hash:$hash</returns>
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
// Converts an ASCII null-terminated string to .NET string
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static string CToString(byte[] cString)
{
int count = 0;
// ReSharper disable once LoopCanBeConvertedToQuery
// LINQ is six times slower
foreach(byte c in cString)
{
int count = 0;
if(c == 0)
break;
// ReSharper disable once LoopCanBeConvertedToQuery
// LINQ is six times slower
foreach(byte c in cString)
{
if(c == 0)
break;
count++;
}
return Encoding.ASCII.GetString(cString, 0, count);
count++;
}
struct RollState
{
public byte[] Window;
return Encoding.ASCII.GetString(cString, 0, count);
}
// ROLLING_WINDOW
public uint H1;
public uint H2;
public uint H3;
public uint N;
}
struct RollState
{
public byte[] Window;
/* A blockhash contains a signature state for a specific (implicit) blocksize.
* The blocksize is given by SSDEEP_BS(index). The h and halfh members are the
* FNV hashes, where halfh stops to be reset after digest is SPAMSUM_LENGTH/2
* long. The halfh hash is needed be able to truncate digest for the second
* output hash to stay compatible with ssdeep output. */
struct BlockhashContext
{
public uint H;
public uint Halfh;
public byte[] Digest;
// ROLLING_WINDOW
public uint H1;
public uint H2;
public uint H3;
public uint N;
}
// SPAMSUM_LENGTH
public byte Halfdigest;
public uint Dlen;
}
/* A blockhash contains a signature state for a specific (implicit) blocksize.
* The blocksize is given by SSDEEP_BS(index). The h and halfh members are the
* FNV hashes, where halfh stops to be reset after digest is SPAMSUM_LENGTH/2
* long. The halfh hash is needed be able to truncate digest for the second
* output hash to stay compatible with ssdeep output. */
struct BlockhashContext
{
public uint H;
public uint Halfh;
public byte[] Digest;
struct FuzzyState
{
public uint Bhstart;
public uint Bhend;
public BlockhashContext[] Bh;
// SPAMSUM_LENGTH
public byte Halfdigest;
public uint Dlen;
}
//NUM_BLOCKHASHES
public ulong TotalSize;
public RollState Roll;
}
struct FuzzyState
{
public uint Bhstart;
public uint Bhend;
public BlockhashContext[] Bh;
//NUM_BLOCKHASHES
public ulong TotalSize;
public RollState Roll;
}
}

View File

@@ -24,141 +24,139 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Runtime.CompilerServices;
namespace Aaru6.Compression
namespace Aaru6.Compression;
/// <summary>Implements the Apple version of RLE</summary>
public class ADC
{
/// <summary>Implements the Apple version of RLE</summary>
public class ADC
const int PLAIN = 1;
const int TWO_BYTE = 2;
const int THREE_BYTE = 3;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetChunkType(byte byt) => (byt & 0x80) == 0x80
? PLAIN
: (byt & 0x40) == 0x40
? THREE_BYTE
: TWO_BYTE;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetChunkSize(byte byt) => GetChunkType(byt) switch
{
const int PLAIN = 1;
const int TWO_BYTE = 2;
const int THREE_BYTE = 3;
PLAIN => (byt & 0x7F) + 1,
TWO_BYTE => ((byt & 0x3F) >> 2) + 3,
THREE_BYTE => (byt & 0x3F) + 4,
_ => -1
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetChunkType(byte byt) => (byt & 0x80) == 0x80
? PLAIN
: (byt & 0x40) == 0x40
? THREE_BYTE
: TWO_BYTE;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetOffset(ReadOnlySpan<byte> chunk) => GetChunkType(chunk[0]) switch
{
PLAIN => 0,
TWO_BYTE => ((chunk[0] & 0x03) << 8) + chunk[1],
THREE_BYTE => (chunk[1] << 8) + chunk[2],
_ => -1
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetChunkSize(byte byt) => GetChunkType(byt) switch
/// <summary>Decompresses a byte buffer that's compressed with ADC</summary>
/// <param name="source">Compressed buffer</param>
/// <param name="destination">Buffer to hold decompressed data</param>
/// <returns>How many bytes are stored on <paramref name="destination" /></returns>
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static int DecodeBuffer(byte[] source, byte[] destination)
{
int inputPosition = 0;
int chunkSize;
int offset;
int chunkType;
int outPosition = 0;
Span<byte> temp = stackalloc byte[3];
while(inputPosition < source.Length)
{
PLAIN => (byt & 0x7F) + 1,
TWO_BYTE => ((byt & 0x3F) >> 2) + 3,
THREE_BYTE => (byt & 0x3F) + 4,
_ => -1
};
byte readByte = source[inputPosition++];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetOffset(ReadOnlySpan<byte> chunk) => GetChunkType(chunk[0]) switch
{
PLAIN => 0,
TWO_BYTE => ((chunk[0] & 0x03) << 8) + chunk[1],
THREE_BYTE => (chunk[1] << 8) + chunk[2],
_ => -1
};
chunkType = GetChunkType(readByte);
/// <summary>Decompresses a byte buffer that's compressed with ADC</summary>
/// <param name="source">Compressed buffer</param>
/// <param name="destination">Buffer to hold decompressed data</param>
/// <returns>How many bytes are stored on <paramref name="destination" /></returns>
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static int DecodeBuffer(byte[] source, byte[] destination)
{
int inputPosition = 0;
int chunkSize;
int offset;
int chunkType;
int outPosition = 0;
Span<byte> temp = stackalloc byte[3];
while(inputPosition < source.Length)
switch(chunkType)
{
byte readByte = source[inputPosition++];
case PLAIN:
chunkSize = GetChunkSize(readByte);
chunkType = GetChunkType(readByte);
if(outPosition + chunkSize > destination.Length)
goto finished;
switch(chunkType)
{
case PLAIN:
chunkSize = GetChunkSize(readByte);
Array.Copy(source, inputPosition, destination, outPosition, chunkSize);
outPosition += chunkSize;
inputPosition += chunkSize;
if(outPosition + chunkSize > destination.Length)
goto finished;
break;
case TWO_BYTE:
chunkSize = GetChunkSize(readByte);
temp[0] = readByte;
temp[1] = source[inputPosition++];
offset = GetOffset(temp);
Array.Copy(source, inputPosition, destination, outPosition, chunkSize);
outPosition += chunkSize;
inputPosition += chunkSize;
if(outPosition + chunkSize > destination.Length)
goto finished;
break;
case TWO_BYTE:
chunkSize = GetChunkSize(readByte);
temp[0] = readByte;
temp[1] = source[inputPosition++];
offset = GetOffset(temp);
if(offset == 0)
{
byte lastByte = destination[outPosition - 1];
if(outPosition + chunkSize > destination.Length)
goto finished;
if(offset == 0)
for(int i = 0; i < chunkSize; i++)
{
byte lastByte = destination[outPosition - 1];
for(int i = 0; i < chunkSize; i++)
{
destination[outPosition] = lastByte;
outPosition++;
}
destination[outPosition] = lastByte;
outPosition++;
}
else
}
else
{
for(int i = 0; i < chunkSize; i++)
{
for(int i = 0; i < chunkSize; i++)
{
destination[outPosition] = destination[outPosition - offset - 1];
outPosition++;
}
destination[outPosition] = destination[outPosition - offset - 1];
outPosition++;
}
}
break;
case THREE_BYTE:
chunkSize = GetChunkSize(readByte);
temp[0] = readByte;
temp[1] = source[inputPosition++];
temp[2] = source[inputPosition++];
offset = GetOffset(temp);
break;
case THREE_BYTE:
chunkSize = GetChunkSize(readByte);
temp[0] = readByte;
temp[1] = source[inputPosition++];
temp[2] = source[inputPosition++];
offset = GetOffset(temp);
if(outPosition + chunkSize > destination.Length)
goto finished;
if(outPosition + chunkSize > destination.Length)
goto finished;
if(offset == 0)
if(offset == 0)
{
byte lastByte = destination[outPosition - 1];
for(int i = 0; i < chunkSize; i++)
{
byte lastByte = destination[outPosition - 1];
for(int i = 0; i < chunkSize; i++)
{
destination[outPosition] = lastByte;
outPosition++;
}
destination[outPosition] = lastByte;
outPosition++;
}
else
}
else
{
for(int i = 0; i < chunkSize; i++)
{
for(int i = 0; i < chunkSize; i++)
{
destination[outPosition] = destination[outPosition - offset - 1];
outPosition++;
}
destination[outPosition] = destination[outPosition - offset - 1];
outPosition++;
}
}
break;
}
break;
}
finished:
return outPosition;
}
finished:
return outPosition;
}
}

View File

@@ -31,94 +31,93 @@
// Copyright © 2018-2019 David Ryskalczyk
// ****************************************************************************/
namespace Aaru6.Compression
namespace Aaru6.Compression;
/// <summary>Implements the Apple version of RLE</summary>
public class AppleRle
{
/// <summary>Implements the Apple version of RLE</summary>
public class AppleRle
const uint DART_CHUNK = 20960;
/// <summary>Decodes a buffer compressed with Apple RLE</summary>
/// <param name="source">Encoded buffer</param>
/// <param name="destination">Buffer where to write the decoded data</param>
/// <returns>The number of decoded bytes</returns>
public static int DecodeBuffer(byte[] source, byte[] destination)
{
const uint DART_CHUNK = 20960;
int count = 0;
bool nextA = true; // true if A, false if B
byte repeatedByteA = 0, repeatedByteB = 0;
bool repeatMode = false; // true if we're repeating, false if we're just copying
int inPosition = 0, outPosition = 0;
/// <summary>Decodes a buffer compressed with Apple RLE</summary>
/// <param name="source">Encoded buffer</param>
/// <param name="destination">Buffer where to write the decoded data</param>
/// <returns>The number of decoded bytes</returns>
public static int DecodeBuffer(byte[] source, byte[] destination)
while(inPosition <= source.Length &&
outPosition <= destination.Length)
{
int count = 0;
bool nextA = true; // true if A, false if B
byte repeatedByteA = 0, repeatedByteB = 0;
bool repeatMode = false; // true if we're repeating, false if we're just copying
int inPosition = 0, outPosition = 0;
while(inPosition <= source.Length &&
outPosition <= destination.Length)
switch(repeatMode)
{
switch(repeatMode)
case true when count > 0:
{
case true when count > 0:
count--;
if(nextA)
{
count--;
if(nextA)
{
nextA = false;
destination[outPosition++] = repeatedByteA;
continue;
}
nextA = true;
destination[outPosition++] = repeatedByteB;
continue;
}
case false when count > 0:
count--;
destination[outPosition++] = source[inPosition++];
continue;
}
if(inPosition == source.Length)
break;
while(true)
{
byte b1 = source[inPosition++];
byte b2 = source[inPosition++];
short s = (short)((b1 << 8) | b2);
if(s == 0 ||
s >= DART_CHUNK ||
s <= -DART_CHUNK)
continue;
if(s < 0)
{
repeatMode = true;
repeatedByteA = source[inPosition++];
repeatedByteB = source[inPosition++];
count = (-s * 2) - 1;
nextA = false;
nextA = false;
destination[outPosition++] = repeatedByteA;
break;
continue;
}
repeatMode = false;
count = (s * 2) - 1;
nextA = true;
destination[outPosition++] = repeatedByteB;
continue;
}
case false when count > 0:
count--;
destination[outPosition++] = source[inPosition++];
break;
}
continue;
}
return outPosition;
if(inPosition == source.Length)
break;
while(true)
{
byte b1 = source[inPosition++];
byte b2 = source[inPosition++];
short s = (short)((b1 << 8) | b2);
if(s == 0 ||
s >= DART_CHUNK ||
s <= -DART_CHUNK)
continue;
if(s < 0)
{
repeatMode = true;
repeatedByteA = source[inPosition++];
repeatedByteB = source[inPosition++];
count = (-s * 2) - 1;
nextA = false;
destination[outPosition++] = repeatedByteA;
break;
}
repeatMode = false;
count = (s * 2) - 1;
destination[outPosition++] = source[inPosition++];
break;
}
}
return outPosition;
}
}

View File

@@ -42,413 +42,409 @@
// Copyright © 1988 Kenji RIKITAKE
// ****************************************************************************/
using System;
using System.IO;
namespace Aaru6.Compression;
namespace Aaru6.Compression
/*
* Based on Japanese version 29-NOV-1988
* LZSS coded by Haruhiko OKUMURA
* Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
* Edited and translated to English by Kenji RIKITAKE
*/
/// <summary>Implements the TeleDisk version of LZH</summary>
public class TeleDiskLzh
{
const int BUFSZ = 512;
/* LZSS Parameters */
const int N = 4096; /* Size of string buffer */
const int F = 60; /* Size of look-ahead buffer */
const int THRESHOLD = 2;
/* Huffman coding parameters */
const int N_CHAR = 256 - THRESHOLD + F;
/* character code (= 0..N_CHAR-1) */
const int T = (N_CHAR * 2) - 1; /* Size of table */
const int ROOT = T - 1; /* root position */
const int MAX_FREQ = 0x8000;
/*
* Based on Japanese version 29-NOV-1988
* LZSS coded by Haruhiko OKUMURA
* Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
* Edited and translated to English by Kenji RIKITAKE
* Tables for encoding/decoding upper 6 bits of
* sliding dictionary pointer
*/
/// <summary>Implements the TeleDisk version of LZH</summary>
public class TeleDiskLzh
/* decoder table */
readonly byte[] _dCode =
{
const int BUFSZ = 512;
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10,
0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14,
0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A,
0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C,
0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x3E, 0x3F
};
/* LZSS Parameters */
readonly byte[] _dLen =
{
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08
};
readonly ushort[] _freq = new ushort[T + 1]; /* cumulative freq table */
const int N = 4096; /* Size of string buffer */
const int F = 60; /* Size of look-ahead buffer */
const int THRESHOLD = 2;
readonly Stream _inStream;
/* Huffman coding parameters */
/*
* pointing parent nodes.
* area [T..(T + N_CHAR - 1)] are pointers for leaves
*/
readonly short[] _prnt = new short[T + N_CHAR];
const int N_CHAR = 256 - THRESHOLD + F;
/* character code (= 0..N_CHAR-1) */
const int T = (N_CHAR * 2) - 1; /* Size of table */
const int ROOT = T - 1; /* root position */
const int MAX_FREQ = 0x8000;
/* pointing children nodes (son[], son[] + 1)*/
readonly short[] _son = new short[T];
readonly byte[] _textBuf = new byte[N + F - 1];
/*
* Tables for encoding/decoding upper 6 bits of
* sliding dictionary pointer
*/
ushort _getbuf;
byte _getlen;
/* decoder table */
readonly byte[] _dCode =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10,
0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14,
0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A,
0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C,
0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x3E, 0x3F
};
Tdlzhuf _tdctl;
readonly byte[] _dLen =
{
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08
};
readonly ushort[] _freq = new ushort[T + 1]; /* cumulative freq table */
/// <summary>Implements the TeleDisk LZH algorithm over the specified stream.</summary>
/// <param name="dataStream">Stream with compressed data.</param>
public TeleDiskLzh(Stream dataStream)
{
int i;
_getbuf = 0;
_getlen = 0;
_tdctl = new Tdlzhuf();
_tdctl.Ibufcnt = _tdctl.Ibufndx = 0; // input buffer is empty
_tdctl.Bufcnt = 0;
StartHuff();
readonly Stream _inStream;
for(i = 0; i < N - F; i++)
_textBuf[i] = 0x20;
/*
* pointing parent nodes.
* area [T..(T + N_CHAR - 1)] are pointers for leaves
*/
readonly short[] _prnt = new short[T + N_CHAR];
_tdctl.R = N - F;
_inStream = dataStream;
}
/* pointing children nodes (son[], son[] + 1)*/
readonly short[] _son = new short[T];
readonly byte[] _textBuf = new byte[N + F - 1];
/* DeCompression
ushort _getbuf;
byte _getlen;
split out initialization code to init_Decode()
Tdlzhuf _tdctl;
*/
/// <summary>Implements the TeleDisk LZH algorithm over the specified stream.</summary>
/// <param name="dataStream">Stream with compressed data.</param>
public TeleDiskLzh(Stream dataStream)
{
int i;
_getbuf = 0;
_getlen = 0;
_tdctl = new Tdlzhuf();
_tdctl.Ibufcnt = _tdctl.Ibufndx = 0; // input buffer is empty
_tdctl.Bufcnt = 0;
StartHuff();
/// <summary>Decompresses data</summary>
/// <param name="buf">Buffer to write the decompressed data to</param>
/// <param name="len">Number of bytes to decompress</param>
/// <returns>Number of decompressed bytes</returns>
public int Decode(out byte[] buf, int len) /* Decoding/Uncompressing */
{
short c;
buf = new byte[len];
int count; // was an unsigned long, seems unnecessary
for(i = 0; i < N - F; i++)
_textBuf[i] = 0x20;
for(count = 0; count < len;)
if(_tdctl.Bufcnt == 0)
{
if((c = DecodeChar()) < 0)
return count; // fatal error
_tdctl.R = N - F;
_inStream = dataStream;
}
/* DeCompression
split out initialization code to init_Decode()
*/
/// <summary>Decompresses data</summary>
/// <param name="buf">Buffer to write the decompressed data to</param>
/// <param name="len">Number of bytes to decompress</param>
/// <returns>Number of decompressed bytes</returns>
public int Decode(out byte[] buf, int len) /* Decoding/Uncompressing */
{
short c;
buf = new byte[len];
int count; // was an unsigned long, seems unnecessary
for(count = 0; count < len;)
if(_tdctl.Bufcnt == 0)
if(c < 256)
{
if((c = DecodeChar()) < 0)
return count; // fatal error
if(c < 256)
{
buf[count] = (byte)c;
_textBuf[_tdctl.R++] = (byte)c;
_tdctl.R &= N - 1;
count++;
}
else
{
short pos;
if((pos = DecodePosition()) < 0)
return count; // fatal error
_tdctl.Bufpos = (ushort)((_tdctl.R - pos - 1) & (N - 1));
_tdctl.Bufcnt = (ushort)(c - 255 + THRESHOLD);
_tdctl.Bufndx = 0;
}
buf[count] = (byte)c;
_textBuf[_tdctl.R++] = (byte)c;
_tdctl.R &= N - 1;
count++;
}
else
{
// still chars from last string
while(_tdctl.Bufndx < _tdctl.Bufcnt &&
count < len)
{
c = _textBuf[(_tdctl.Bufpos + _tdctl.Bufndx) & (N - 1)];
buf[count] = (byte)c;
_tdctl.Bufndx++;
_textBuf[_tdctl.R++] = (byte)c;
_tdctl.R &= N - 1;
count++;
}
short pos;
// reset bufcnt after copy string from text_buf[]
if(_tdctl.Bufndx >= _tdctl.Bufcnt)
_tdctl.Bufndx = _tdctl.Bufcnt = 0;
if((pos = DecodePosition()) < 0)
return count; // fatal error
_tdctl.Bufpos = (ushort)((_tdctl.R - pos - 1) & (N - 1));
_tdctl.Bufcnt = (ushort)(c - 255 + THRESHOLD);
_tdctl.Bufndx = 0;
}
}
else
{
// still chars from last string
while(_tdctl.Bufndx < _tdctl.Bufcnt &&
count < len)
{
c = _textBuf[(_tdctl.Bufpos + _tdctl.Bufndx) & (N - 1)];
buf[count] = (byte)c;
_tdctl.Bufndx++;
_textBuf[_tdctl.R++] = (byte)c;
_tdctl.R &= N - 1;
count++;
}
return count; // count == len, success
}
long DataRead(out byte[] buf, long size)
{
if(size > _inStream.Length - _inStream.Position)
size = _inStream.Length - _inStream.Position;
buf = new byte[size];
_inStream.Read(buf, 0, (int)size);
return size;
}
int NextWord()
{
if(_tdctl.Ibufndx >= _tdctl.Ibufcnt)
{
_tdctl.Ibufndx = 0;
_tdctl.Ibufcnt = (ushort)DataRead(out _tdctl.Inbuf, BUFSZ);
if(_tdctl.Ibufcnt <= 0)
return -1;
// reset bufcnt after copy string from text_buf[]
if(_tdctl.Bufndx >= _tdctl.Bufcnt)
_tdctl.Bufndx = _tdctl.Bufcnt = 0;
}
while(_getlen <= 8)
{
// typically reads a word at a time
_getbuf |= (ushort)(_tdctl.Inbuf[_tdctl.Ibufndx++] << (8 - _getlen));
_getlen += 8;
}
return count; // count == len, success
}
return 0;
}
long DataRead(out byte[] buf, long size)
{
if(size > _inStream.Length - _inStream.Position)
size = _inStream.Length - _inStream.Position;
int GetBit() /* get one bit */
buf = new byte[size];
_inStream.Read(buf, 0, (int)size);
return size;
}
int NextWord()
{
if(_tdctl.Ibufndx >= _tdctl.Ibufcnt)
{
if(NextWord() < 0)
_tdctl.Ibufndx = 0;
_tdctl.Ibufcnt = (ushort)DataRead(out _tdctl.Inbuf, BUFSZ);
if(_tdctl.Ibufcnt <= 0)
return -1;
short i = (short)_getbuf;
_getbuf <<= 1;
_getlen--;
return i < 0 ? 1 : 0;
}
int GetByte() /* get a byte */
while(_getlen <= 8)
{
if(NextWord() != 0)
return -1;
ushort i = _getbuf;
_getbuf <<= 8;
_getlen -= 8;
i = (ushort)(i >> 8);
return i;
// typically reads a word at a time
_getbuf |= (ushort)(_tdctl.Inbuf[_tdctl.Ibufndx++] << (8 - _getlen));
_getlen += 8;
}
/* initialize freq tree */
return 0;
}
void StartHuff()
int GetBit() /* get one bit */
{
if(NextWord() < 0)
return -1;
short i = (short)_getbuf;
_getbuf <<= 1;
_getlen--;
return i < 0 ? 1 : 0;
}
int GetByte() /* get a byte */
{
if(NextWord() != 0)
return -1;
ushort i = _getbuf;
_getbuf <<= 8;
_getlen -= 8;
i = (ushort)(i >> 8);
return i;
}
/* initialize freq tree */
void StartHuff()
{
int i;
for(i = 0; i < N_CHAR; i++)
{
int i;
_freq[i] = 1;
_son[i] = (short)(i + T);
_prnt[i + T] = (short)i;
}
for(i = 0; i < N_CHAR; i++)
i = 0;
int j = N_CHAR;
while(j <= ROOT)
{
_freq[j] = (ushort)(_freq[i] + _freq[i + 1]);
_son[j] = (short)i;
_prnt[i] = _prnt[i + 1] = (short)j;
i += 2;
j++;
}
_freq[T] = 0xffff;
_prnt[ROOT] = 0;
}
/* reconstruct freq tree */
void Reconst()
{
short i, k;
/* halven cumulative freq for leaf nodes */
short j = 0;
for(i = 0; i < T; i++)
if(_son[i] >= T)
{
_freq[i] = 1;
_son[i] = (short)(i + T);
_prnt[i + T] = (short)i;
}
i = 0;
int j = N_CHAR;
while(j <= ROOT)
{
_freq[j] = (ushort)(_freq[i] + _freq[i + 1]);
_son[j] = (short)i;
_prnt[i] = _prnt[i + 1] = (short)j;
i += 2;
_freq[j] = (ushort)((_freq[i] + 1) / 2);
_son[j] = _son[i];
j++;
}
_freq[T] = 0xffff;
_prnt[ROOT] = 0;
/* make a tree : first, connect children nodes */
for(i = 0, j = N_CHAR; j < T; i += 2, j++)
{
k = (short)(i + 1);
ushort f = _freq[j] = (ushort)(_freq[i] + _freq[k]);
for(k = (short)(j - 1); f < _freq[k]; k--) {}
k++;
ushort l = (ushort)((j - k) * 2);
Array.ConstrainedCopy(_freq, k, _freq, k + 1, l);
_freq[k] = f;
Array.ConstrainedCopy(_son, k, _son, k + 1, l);
_son[k] = i;
}
/* reconstruct freq tree */
/* connect parent nodes */
for(i = 0; i < T; i++)
if((k = _son[i]) >= T)
_prnt[k] = i;
else
_prnt[k] = _prnt[k + 1] = i;
}
void Reconst()
/* update freq tree */
void Update(int c)
{
if(_freq[ROOT] == MAX_FREQ)
Reconst();
c = _prnt[c + T];
do
{
short i, k;
int k = ++_freq[c];
/* halven cumulative freq for leaf nodes */
short j = 0;
/* swap nodes to keep the tree freq-ordered */
int l;
for(i = 0; i < T; i++)
if(_son[i] >= T)
{
_freq[j] = (ushort)((_freq[i] + 1) / 2);
_son[j] = _son[i];
j++;
}
if(k <= _freq[l = c + 1])
continue;
/* make a tree : first, connect children nodes */
for(i = 0, j = N_CHAR; j < T; i += 2, j++)
{
k = (short)(i + 1);
ushort f = _freq[j] = (ushort)(_freq[i] + _freq[k]);
while(k > _freq[++l]) {}
for(k = (short)(j - 1); f < _freq[k]; k--) {}
l--;
_freq[c] = _freq[l];
_freq[l] = (ushort)k;
k++;
ushort l = (ushort)((j - k) * 2);
int i = _son[c];
_prnt[i] = (short)l;
Array.ConstrainedCopy(_freq, k, _freq, k + 1, l);
_freq[k] = f;
Array.ConstrainedCopy(_son, k, _son, k + 1, l);
_son[k] = i;
}
if(i < T)
_prnt[i + 1] = (short)l;
/* connect parent nodes */
for(i = 0; i < T; i++)
if((k = _son[i]) >= T)
_prnt[k] = i;
else
_prnt[k] = _prnt[k + 1] = i;
}
int j = _son[l];
_son[l] = (short)i;
/* update freq tree */
_prnt[j] = (short)c;
void Update(int c)
if(j < T)
_prnt[j + 1] = (short)c;
_son[c] = (short)j;
c = l;
} while((c = _prnt[c]) != 0); /* do it until reaching the root */
}
short DecodeChar()
{
ushort c = (ushort)_son[ROOT];
/*
* start searching tree from the root to leaves.
* choose node #(son[]) if input bit == 0
* else choose #(son[]+1) (input bit == 1)
*/
while(c < T)
{
if(_freq[ROOT] == MAX_FREQ)
Reconst();
int ret;
c = _prnt[c + T];
do
{
int k = ++_freq[c];
/* swap nodes to keep the tree freq-ordered */
int l;
if(k <= _freq[l = c + 1])
continue;
while(k > _freq[++l]) {}
l--;
_freq[c] = _freq[l];
_freq[l] = (ushort)k;
int i = _son[c];
_prnt[i] = (short)l;
if(i < T)
_prnt[i + 1] = (short)l;
int j = _son[l];
_son[l] = (short)i;
_prnt[j] = (short)c;
if(j < T)
_prnt[j + 1] = (short)c;
_son[c] = (short)j;
c = l;
} while((c = _prnt[c]) != 0); /* do it until reaching the root */
}
short DecodeChar()
{
ushort c = (ushort)_son[ROOT];
/*
* start searching tree from the root to leaves.
* choose node #(son[]) if input bit == 0
* else choose #(son[]+1) (input bit == 1)
*/
while(c < T)
{
int ret;
if((ret = GetBit()) < 0)
return -1;
c += (ushort)ret;
c = (ushort)_son[c];
}
c -= T;
Update(c);
return (short)c;
}
short DecodePosition()
{
short bit;
/* decode upper 6 bits from given table */
if((bit = (short)GetByte()) < 0)
if((ret = GetBit()) < 0)
return -1;
ushort i = (ushort)bit;
ushort c = (ushort)(_dCode[i] << 6);
ushort j = _dLen[i];
/* input lower 6 bits directly */
j -= 2;
while(j-- > 0)
{
if((bit = (short)GetBit()) < 0)
return -1;
i = (ushort)((i << 1) + bit);
}
return (short)(c | (i & 0x3f));
c += (ushort)ret;
c = (ushort)_son[c];
}
/* update when cumulative frequency */
/* reaches to this value */
struct Tdlzhuf
c -= T;
Update(c);
return (short)c;
}
short DecodePosition()
{
short bit;
/* decode upper 6 bits from given table */
if((bit = (short)GetByte()) < 0)
return -1;
ushort i = (ushort)bit;
ushort c = (ushort)(_dCode[i] << 6);
ushort j = _dLen[i];
/* input lower 6 bits directly */
j -= 2;
while(j-- > 0)
{
public ushort R, Bufcnt, Bufndx, Bufpos, // string buffer
// the following to allow block reads from input in next_word()
Ibufcnt, Ibufndx; // input buffer counters
public byte[] Inbuf; // input buffer
if((bit = (short)GetBit()) < 0)
return -1;
i = (ushort)((i << 1) + bit);
}
return (short)(c | (i & 0x3f));
}
/* update when cumulative frequency */
/* reaches to this value */
struct Tdlzhuf
{
public ushort R, Bufcnt, Bufndx, Bufpos, // string buffer
// the following to allow block reads from input in next_word()
Ibufcnt, Ibufndx; // input buffer counters
public byte[] Inbuf; // input buffer
}
}

View File

@@ -6,68 +6,68 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aaru.Checksums" Version="5.3.1" />
<PackageReference Include="Aaru.Compression" Version="5.3.1" />
<PackageReference Include="Aaru.Compression.Native" Version="6.0.0-alpha9" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
<PackageReference Include="DotNetZip" Version="1.16.0" />
<PackageReference Include="SharpCompress" Version="0.32.2" />
<PackageReference Include="Aaru.Checksums" Version="5.3.1"/>
<PackageReference Include="Aaru.Compression" Version="5.3.1"/>
<PackageReference Include="Aaru.Compression.Native" Version="6.0.0-alpha9"/>
<PackageReference Include="BenchmarkDotNet" Version="0.13.2"/>
<PackageReference Include="DotNetZip" Version="1.16.0"/>
<PackageReference Include="SharpCompress" Version="0.32.2"/>
</ItemGroup>
<ItemGroup>
<None Remove="data\random" />
<None Remove="data\random"/>
<Content Include="data\random">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\gzip.gz" />
<None Remove="data\gzip.gz"/>
<Content Include="data\gzip.gz">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\bzip2.bz2" />
<None Remove="data\bzip2.bz2"/>
<Content Include="data\bzip2.bz2">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\apple_rle.bin" />
<None Remove="data\apple_rle.bin"/>
<Content Include="data\apple_rle.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\teledisk_lzh.bin" />
<None Remove="data\teledisk_lzh.bin"/>
<Content Include="data\teledisk_lzh.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\adc.bin" />
<None Remove="data\adc.bin"/>
<Content Include="data\adc.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\lzip.lz" />
<None Remove="data\lzip.lz"/>
<Content Include="data\lzip.lz">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\lzma.bin" />
<None Remove="data\lzma.bin"/>
<Content Include="data\lzma.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\flac.flac" />
<None Remove="data\flac.flac"/>
<Content Include="data\flac.flac">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\audio.bin" />
<None Remove="data\audio.bin"/>
<Content Include="data\audio.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Remove="data\data.bin" />
<None Remove="data\data.bin"/>
<Content Include="data\data.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Aaru6.Checksums\Aaru6.Checksums.csproj" />
<ProjectReference Include="..\Aaru6.Compression\Aaru6.Compression.csproj" />
<ProjectReference Include="..\Aaru6.Checksums\Aaru6.Checksums.csproj"/>
<ProjectReference Include="..\Aaru6.Compression\Aaru6.Compression.csproj"/>
</ItemGroup>
<ItemGroup>
<Folder Include="data" />
<Folder Include="data"/>
</ItemGroup>
</Project>

View File

@@ -3,380 +3,327 @@ using AaruBenchmark.Compression;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
namespace AaruBenchmark
namespace AaruBenchmark;
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class AppleRleBenchs
{
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class AppleRleBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.Aaru.AppleRle();
[Benchmark]
public void Aaru6() => Aaru6Compressions.AppleRle();
[Benchmark]
public void AaruNative() => Compression.AaruNative.AppleRle();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class TeleDiskLzhBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.Aaru.TeleDiskLzh();
[Benchmark]
public void Aaru6() => Aaru6Compressions.TeleDiskLzh();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class ADCBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.SharpCompress.ADC();
[Benchmark]
public void Aaru6() => Aaru6Compressions.ADC();
[Benchmark]
public void AaruNative() => Compression.AaruNative.ADC();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class GzipBenchs
{
[Benchmark]
public void SharpCompress() => Compression.SharpCompress.Gzip();
[Benchmark(Baseline = true)]
public void DotNetRuntime() => NetRuntime.Gzip();
[Benchmark]
public void DotNetZip() => Compression.DotNetZip.Gzip();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressGzipBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.SharpCompress.CompressGzip();
[Benchmark]
public void Aaru6() => NetRuntime.CompressGzip();
[Benchmark]
public void DotNetZip() => Compression.DotNetZip.CompressGzip();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Bzip2Benchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.Bzip2();
[Benchmark]
public void DotNetZip() => Compression.DotNetZip.Bzip2();
[Benchmark]
public void AaruNative() => Compression.AaruNative.Bzip2();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressBzip2Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.SharpCompress.CompressBzip2();
[Benchmark]
public void Aaru6() => DotNetZip.CompressBzip2();
[Benchmark]
public void AaruNative() => Compression.AaruNative.CompressBzip2();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class LzipBenchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.Lzip();
[Benchmark]
public void AaruNative() => Compression.AaruNative.Lzip();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressLzipBenchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.CompressLzip();
[Benchmark]
public void AaruNative() => Compression.AaruNative.CompressLzip();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class LzmaBenchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.Lzma();
[Benchmark]
public void AaruNative() => Compression.AaruNative.Lzma();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressLzmaBenchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.CompressLzma();
[Benchmark]
public void AaruNative() => Compression.AaruNative.CompressLzma();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class FlacBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.Aaru.Flac();
[Benchmark]
public void AaruNative() => Compression.AaruNative.Flac();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressFlacBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.Aaru.CompressFlac();
[Benchmark]
public void AaruNative() => Compression.AaruNative.CompressFlac();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Adler32Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Adler32();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Adler32();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Adler32();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Fletcher16Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Fletcher16();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Fletcher16();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Fletcher16();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Fletcher32Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Fletcher32();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Fletcher32();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Fletcher32();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Crc16CcittBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Crc16Ccitt();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Crc16Ccitt();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Crc16Ccitt();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Crc16Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Crc16();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Crc16();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Crc16();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Crc32Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Crc32();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Crc32();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Crc32();
[Benchmark]
public void rhash() => RHash.Crc32();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Crc64Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Crc64();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Crc64();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Crc64();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Md5Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Md5();
[Benchmark]
public void OpenSSL() => OpenSsl.Md5();
[Benchmark]
public void rhash() => RHash.Md5();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Sha1Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Sha1();
[Benchmark]
public void OpenSSL() => OpenSsl.Sha1();
[Benchmark]
public void rhash() => RHash.Sha1();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Sha256Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Sha256();
[Benchmark]
public void OpenSSL() => OpenSsl.Sha256();
[Benchmark]
public void rhash() => RHash.Sha256();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Sha384Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Sha384();
[Benchmark]
public void OpenSSL() => OpenSsl.Sha384();
[Benchmark]
public void rhash() => RHash.Sha384();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class Sha512Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Sha512();
[Benchmark]
public void OpenSSL() => OpenSsl.Sha512();
[Benchmark]
public void rhash() => RHash.Sha512();
}
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net70)]
[SimpleJob(RuntimeMoniker.NativeAot70)]
public class SpamSumBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.SpamSum();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.SpamSum();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.SpamSum();
[Benchmark]
public void ssdeep() => Checksums.Aaru.CliSpamSum();
}
[Benchmark(Baseline = true)]
public void Aaru() => Compression.Aaru.AppleRle();
[Benchmark]
public void Aaru6() => Aaru6Compressions.AppleRle();
[Benchmark]
public void AaruNative() => Compression.AaruNative.AppleRle();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class TeleDiskLzhBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.Aaru.TeleDiskLzh();
[Benchmark]
public void Aaru6() => Aaru6Compressions.TeleDiskLzh();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class ADCBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.SharpCompress.ADC();
[Benchmark]
public void Aaru6() => Aaru6Compressions.ADC();
[Benchmark]
public void AaruNative() => Compression.AaruNative.ADC();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class GzipBenchs
{
[Benchmark]
public void SharpCompress() => Compression.SharpCompress.Gzip();
[Benchmark(Baseline = true)]
public void DotNetRuntime() => NetRuntime.Gzip();
[Benchmark]
public void DotNetZip() => Compression.DotNetZip.Gzip();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressGzipBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.SharpCompress.CompressGzip();
[Benchmark]
public void Aaru6() => NetRuntime.CompressGzip();
[Benchmark]
public void DotNetZip() => Compression.DotNetZip.CompressGzip();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Bzip2Benchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.Bzip2();
[Benchmark]
public void DotNetZip() => Compression.DotNetZip.Bzip2();
[Benchmark]
public void AaruNative() => Compression.AaruNative.Bzip2();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressBzip2Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.SharpCompress.CompressBzip2();
[Benchmark]
public void Aaru6() => DotNetZip.CompressBzip2();
[Benchmark]
public void AaruNative() => Compression.AaruNative.CompressBzip2();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class LzipBenchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.Lzip();
[Benchmark]
public void AaruNative() => Compression.AaruNative.Lzip();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressLzipBenchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.CompressLzip();
[Benchmark]
public void AaruNative() => Compression.AaruNative.CompressLzip();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class LzmaBenchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.Lzma();
[Benchmark]
public void AaruNative() => Compression.AaruNative.Lzma();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressLzmaBenchs
{
[Benchmark(Baseline = true)]
public void SharpCompress() => Compression.SharpCompress.CompressLzma();
[Benchmark]
public void AaruNative() => Compression.AaruNative.CompressLzma();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class FlacBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.Aaru.Flac();
[Benchmark]
public void AaruNative() => Compression.AaruNative.Flac();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class CompressFlacBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Compression.Aaru.CompressFlac();
[Benchmark]
public void AaruNative() => Compression.AaruNative.CompressFlac();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Adler32Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Adler32();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Adler32();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Adler32();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Fletcher16Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Fletcher16();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Fletcher16();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Fletcher16();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Fletcher32Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Fletcher32();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Fletcher32();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Fletcher32();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Crc16CcittBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Crc16Ccitt();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Crc16Ccitt();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Crc16Ccitt();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Crc16Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Crc16();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Crc16();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Crc16();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Crc32Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Crc32();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Crc32();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Crc32();
[Benchmark]
public void rhash() => RHash.Crc32();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Crc64Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Crc64();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.Crc64();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.Crc64();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Md5Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Md5();
[Benchmark]
public void OpenSSL() => OpenSsl.Md5();
[Benchmark]
public void rhash() => RHash.Md5();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Sha1Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Sha1();
[Benchmark]
public void OpenSSL() => OpenSsl.Sha1();
[Benchmark]
public void rhash() => RHash.Sha1();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Sha256Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Sha256();
[Benchmark]
public void OpenSSL() => OpenSsl.Sha256();
[Benchmark]
public void rhash() => RHash.Sha256();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Sha384Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Sha384();
[Benchmark]
public void OpenSSL() => OpenSsl.Sha384();
[Benchmark]
public void rhash() => RHash.Sha384();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class Sha512Benchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.Sha512();
[Benchmark]
public void OpenSSL() => OpenSsl.Sha512();
[Benchmark]
public void rhash() => RHash.Sha512();
}
[SimpleJob(RuntimeMoniker.Net60), SimpleJob(RuntimeMoniker.Net70), SimpleJob(RuntimeMoniker.NativeAot70)]
public class SpamSumBenchs
{
[Benchmark(Baseline = true)]
public void Aaru() => Checksums.Aaru.SpamSum();
[Benchmark]
public void Aaru6() => Checksums.Aaru6.SpamSum();
[Benchmark]
public void AaruNative() => Checksums.AaruNative.SpamSum();
[Benchmark]
public void ssdeep() => Checksums.Aaru.CliSpamSum();
}

View File

@@ -5,342 +5,341 @@ using System.Linq;
using Aaru.Checksums;
using Aaru.CommonTypes.Interfaces;
namespace AaruBenchmark.Checksums
namespace AaruBenchmark.Checksums;
public class Aaru
{
public class Aaru
static readonly byte[] _expectedRandomAdler32 =
{
static readonly byte[] _expectedRandomAdler32 =
{
0x37, 0x28, 0xd1, 0x86
};
static readonly byte[] _expectedRandomFletcher16 =
{
0x33, 0x57
};
static readonly byte[] _expectedRandomFletcher32 =
{
0x21, 0x12, 0x61, 0xF5
};
static readonly byte[] _expectedRandomCrc16Ccitt =
{
0xC9, 0xBF
};
static readonly byte[] _expectedRandomCrc16 =
{
0x2d, 0x6d
};
static readonly byte[] _expectedRandomCrc32 =
{
0x2b, 0x6e, 0x68, 0x54
};
static readonly byte[] _expectedRandomCrc64 =
{
0xbf, 0x09, 0x99, 0x2c, 0xc5, 0xed, 0xe3, 0x8e
};
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
public static void Fletcher16()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher16Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomFletcher16.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomFletcher16[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Fletcher32()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomFletcher32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomFletcher32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Adler32()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Adler32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomAdler32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomAdler32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc16Ccitt()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16CCITTContext();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc16Ccitt.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc16Ccitt[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc16()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16IBMContext();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc16.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc16[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc32()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc64()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc64Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc64.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc64[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Md5()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Md5Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomMd5.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomMd5[i]).Any())
throw new Exception("Invalid hash value");
}
public static void SpamSum()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new SpamSumContext();
ctx.Update(data);
string result = ctx.End();
}
public static void CliSpamSum()
{
var proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.FileName = "/usr/bin/ssdeep";
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.ArgumentList.Add(Path.Combine(Program.Folder, "random"));
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
}
public static void Sha1()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Sha1Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomSha1.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomSha1[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha256()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Sha256Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomSha256.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomSha256[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha384()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Sha384Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomSha384.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomSha384[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha512()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Sha512Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomSha512.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomSha512[i]).Any())
throw new Exception("Invalid hash value");
}
0x37, 0x28, 0xd1, 0x86
};
static readonly byte[] _expectedRandomFletcher16 =
{
0x33, 0x57
};
static readonly byte[] _expectedRandomFletcher32 =
{
0x21, 0x12, 0x61, 0xF5
};
static readonly byte[] _expectedRandomCrc16Ccitt =
{
0xC9, 0xBF
};
static readonly byte[] _expectedRandomCrc16 =
{
0x2d, 0x6d
};
static readonly byte[] _expectedRandomCrc32 =
{
0x2b, 0x6e, 0x68, 0x54
};
static readonly byte[] _expectedRandomCrc64 =
{
0xbf, 0x09, 0x99, 0x2c, 0xc5, 0xed, 0xe3, 0x8e
};
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
public static void Fletcher16()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher16Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomFletcher16.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomFletcher16[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Fletcher32()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomFletcher32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomFletcher32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Adler32()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Adler32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomAdler32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomAdler32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc16Ccitt()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16CCITTContext();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc16Ccitt.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc16Ccitt[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc16()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16IBMContext();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc16.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc16[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc32()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc64()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc64Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc64.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc64[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Md5()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Md5Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomMd5.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomMd5[i]).Any())
throw new Exception("Invalid hash value");
}
public static void SpamSum()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new SpamSumContext();
ctx.Update(data);
string result = ctx.End();
}
public static void CliSpamSum()
{
var proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.FileName = "/usr/bin/ssdeep";
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.ArgumentList.Add(Path.Combine(Program.Folder, "random"));
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
}
public static void Sha1()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Sha1Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomSha1.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomSha1[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha256()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Sha256Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomSha256.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomSha256[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha384()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Sha384Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomSha384.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomSha384[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha512()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Sha512Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomSha512.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomSha512[i]).Any())
throw new Exception("Invalid hash value");
}
}

View File

@@ -4,243 +4,242 @@ using System.Linq;
using Aaru.CommonTypes.Interfaces;
using Aaru6.Checksums;
namespace AaruBenchmark.Checksums
namespace AaruBenchmark.Checksums;
public class Aaru6
{
public class Aaru6
static readonly byte[] _expectedRandomAdler32 =
{
static readonly byte[] _expectedRandomAdler32 =
{
0x37, 0x28, 0xd1, 0x86
};
0x37, 0x28, 0xd1, 0x86
};
static readonly byte[] _expectedRandomFletcher16 =
{
0x33, 0x57
};
static readonly byte[] _expectedRandomFletcher16 =
{
0x33, 0x57
};
static readonly byte[] _expectedRandomFletcher32 =
{
0x21, 0x12, 0x61, 0xF5
};
static readonly byte[] _expectedRandomFletcher32 =
{
0x21, 0x12, 0x61, 0xF5
};
static readonly byte[] _expectedRandomCrc16Ccitt =
{
0x36, 0x40
};
static readonly byte[] _expectedRandomCrc16Ccitt =
{
0x36, 0x40
};
static readonly byte[] _expectedRandomCrc16 =
{
0x2d, 0x6d
};
static readonly byte[] _expectedRandomCrc16 =
{
0x2d, 0x6d
};
static readonly byte[] _expectedRandomCrc32 =
{
0x2b, 0x6e, 0x68, 0x54
};
static readonly byte[] _expectedRandomCrc32 =
{
0x2b, 0x6e, 0x68, 0x54
};
static readonly byte[] _expectedRandomCrc64 =
{
0xbf, 0x09, 0x99, 0x2c, 0xc5, 0xed, 0xe3, 0x8e
};
static readonly byte[] _expectedRandomCrc64 =
{
0xbf, 0x09, 0x99, 0x2c, 0xc5, 0xed, 0xe3, 0x8e
};
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
public static void Fletcher16()
{
Native.ForceManaged = true;
public static void Fletcher16()
{
Native.ForceManaged = true;
byte[] data = new byte[1048576];
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher16Context();
ctx.Update(data);
byte[] result = ctx.Final();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher16Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomFletcher16.Length)
throw new Exception("Invalid hash length");
if(result?.Length != _expectedRandomFletcher16.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomFletcher16[i]).Any())
throw new Exception("Invalid hash value");
}
if(result.Where((t, i) => t != _expectedRandomFletcher16[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Fletcher32()
{
Native.ForceManaged = true;
public static void Fletcher32()
{
Native.ForceManaged = true;
byte[] data = new byte[1048576];
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher32Context();
ctx.Update(data);
byte[] result = ctx.Final();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomFletcher32.Length)
throw new Exception("Invalid hash length");
if(result?.Length != _expectedRandomFletcher32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomFletcher32[i]).Any())
throw new Exception("Invalid hash value");
}
if(result.Where((t, i) => t != _expectedRandomFletcher32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Adler32()
{
Native.ForceManaged = true;
public static void Adler32()
{
Native.ForceManaged = true;
byte[] data = new byte[1048576];
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Adler32Context();
ctx.Update(data);
byte[] result = ctx.Final();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Adler32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomAdler32.Length)
throw new Exception("Invalid hash length");
if(result?.Length != _expectedRandomAdler32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomAdler32[i]).Any())
throw new Exception("Invalid hash value");
}
if(result.Where((t, i) => t != _expectedRandomAdler32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc16Ccitt()
{
Native.ForceManaged = true;
public static void Crc16Ccitt()
{
Native.ForceManaged = true;
byte[] data = new byte[1048576];
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16CCITTContext();
ctx.Update(data);
byte[] result = ctx.Final();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16CCITTContext();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc16Ccitt.Length)
throw new Exception("Invalid hash length");
if(result?.Length != _expectedRandomCrc16Ccitt.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc16Ccitt[i]).Any())
throw new Exception("Invalid hash value");
}
if(result.Where((t, i) => t != _expectedRandomCrc16Ccitt[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc16()
{
Native.ForceManaged = true;
public static void Crc16()
{
Native.ForceManaged = true;
byte[] data = new byte[1048576];
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16IBMContext();
ctx.Update(data);
byte[] result = ctx.Final();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16IBMContext();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc16.Length)
throw new Exception("Invalid hash length");
if(result?.Length != _expectedRandomCrc16.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc16[i]).Any())
throw new Exception("Invalid hash value");
}
if(result.Where((t, i) => t != _expectedRandomCrc16[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc32()
{
Native.ForceManaged = true;
public static void Crc32()
{
Native.ForceManaged = true;
byte[] data = new byte[1048576];
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc32Context();
ctx.Update(data);
byte[] result = ctx.Final();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc32.Length)
throw new Exception("Invalid hash length");
if(result?.Length != _expectedRandomCrc32.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc32[i]).Any())
throw new Exception("Invalid hash value");
}
if(result.Where((t, i) => t != _expectedRandomCrc32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Crc64()
{
Native.ForceManaged = true;
public static void Crc64()
{
Native.ForceManaged = true;
byte[] data = new byte[1048576];
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc64Context();
ctx.Update(data);
byte[] result = ctx.Final();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc64Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomCrc64.Length)
throw new Exception("Invalid hash length");
if(result?.Length != _expectedRandomCrc64.Length)
throw new Exception("Invalid hash length");
if(result.Where((t, i) => t != _expectedRandomCrc64[i]).Any())
throw new Exception("Invalid hash value");
}
if(result.Where((t, i) => t != _expectedRandomCrc64[i]).Any())
throw new Exception("Invalid hash value");
}
public static void SpamSum()
{
byte[] data = new byte[1048576];
public static void SpamSum()
{
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new SpamSumContext();
ctx.Update(data);
string result = ctx.End();
}
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new SpamSumContext();
ctx.Update(data);
string result = ctx.End();
}
}

View File

@@ -5,270 +5,269 @@ using System.Runtime.InteropServices;
using Aaru.CommonTypes.Interfaces;
using Aaru6.Checksums;
namespace AaruBenchmark.Checksums
namespace AaruBenchmark.Checksums;
public class AaruNative
{
public class AaruNative
static readonly byte[] _expectedRandomAdler32 =
{
static readonly byte[] _expectedRandomAdler32 =
{
0x37, 0x28, 0xd1, 0x86
};
static readonly byte[] _expectedRandomFletcher16 =
{
0x33, 0x57
};
static readonly byte[] _expectedRandomFletcher32 =
{
0x21, 0x12, 0x61, 0xF5
};
static readonly byte[] _expectedRandomCrc16Ccitt =
{
0x36, 0x40
};
static readonly byte[] _expectedRandomCrc16 =
{
0x2d, 0x6d
};
static readonly byte[] _expectedRandomCrc32 =
{
0x2b, 0x6e, 0x68, 0x54
};
static readonly byte[] _expectedRandomCrc64 =
{
0xbf, 0x09, 0x99, 0x2c, 0xc5, 0xed, 0xe3, 0x8e
};
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern IntPtr spamsum_init();
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int spamsum_update(IntPtr ctx, byte[] data, uint len);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int spamsum_final(IntPtr ctx, byte[] result);
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern void spamsum_free(IntPtr ctx);
public static void Fletcher16()
{
Native.ForceManaged = false;
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher16Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomFletcher16.Length)
throw new Exception("Invalid hash length");
0x37, 0x28, 0xd1, 0x86
};
static readonly byte[] _expectedRandomFletcher16 =
{
0x33, 0x57
};
static readonly byte[] _expectedRandomFletcher32 =
{
0x21, 0x12, 0x61, 0xF5
};
static readonly byte[] _expectedRandomCrc16Ccitt =
{
0x36, 0x40
};
static readonly byte[] _expectedRandomCrc16 =
{
0x2d, 0x6d
};
static readonly byte[] _expectedRandomCrc32 =
{
0x2b, 0x6e, 0x68, 0x54
};
static readonly byte[] _expectedRandomCrc64 =
{
0xbf, 0x09, 0x99, 0x2c, 0xc5, 0xed, 0xe3, 0x8e
};
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern IntPtr spamsum_init();
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int spamsum_update(IntPtr ctx, byte[] data, uint len);
if(result.Where((t, i) => t != _expectedRandomFletcher16[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Fletcher32()
{
Native.ForceManaged = false;
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern int spamsum_final(IntPtr ctx, byte[] result);
byte[] data = new byte[1048576];
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern void spamsum_free(IntPtr ctx);
public static void Fletcher16()
{
Native.ForceManaged = false;
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher16Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result?.Length != _expectedRandomFletcher16.Length)
throw new Exception("Invalid hash length");
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result.Where((t, i) => t != _expectedRandomFletcher16[i]).Any())
throw new Exception("Invalid hash value");
}
if(result?.Length != _expectedRandomFletcher32.Length)
throw new Exception("Invalid hash length");
public static void Fletcher32()
{
Native.ForceManaged = false;
if(result.Where((t, i) => t != _expectedRandomFletcher32[i]).Any())
throw new Exception("Invalid hash value");
}
byte[] data = new byte[1048576];
public static void Adler32()
{
Native.ForceManaged = false;
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
byte[] data = new byte[1048576];
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Fletcher32Context();
ctx.Update(data);
byte[] result = ctx.Final();
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
if(result?.Length != _expectedRandomFletcher32.Length)
throw new Exception("Invalid hash length");
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Adler32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result.Where((t, i) => t != _expectedRandomFletcher32[i]).Any())
throw new Exception("Invalid hash value");
}
if(result?.Length != _expectedRandomAdler32.Length)
throw new Exception("Invalid hash length");
public static void Adler32()
{
Native.ForceManaged = false;
if(result.Where((t, i) => t != _expectedRandomAdler32[i]).Any())
throw new Exception("Invalid hash value");
}
byte[] data = new byte[1048576];
public static void Crc16Ccitt()
{
Native.ForceManaged = false;
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
byte[] data = new byte[1048576];
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Adler32Context();
ctx.Update(data);
byte[] result = ctx.Final();
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
if(result?.Length != _expectedRandomAdler32.Length)
throw new Exception("Invalid hash length");
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16CCITTContext();
ctx.Update(data);
byte[] result = ctx.Final();
if(result.Where((t, i) => t != _expectedRandomAdler32[i]).Any())
throw new Exception("Invalid hash value");
}
if(result?.Length != _expectedRandomCrc16Ccitt.Length)
throw new Exception("Invalid hash length");
public static void Crc16Ccitt()
{
Native.ForceManaged = false;
if(result.Where((t, i) => t != _expectedRandomCrc16Ccitt[i]).Any())
throw new Exception("Invalid hash value");
}
byte[] data = new byte[1048576];
public static void Crc16()
{
Native.ForceManaged = false;
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
byte[] data = new byte[1048576];
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16CCITTContext();
ctx.Update(data);
byte[] result = ctx.Final();
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
if(result?.Length != _expectedRandomCrc16Ccitt.Length)
throw new Exception("Invalid hash length");
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16IBMContext();
ctx.Update(data);
byte[] result = ctx.Final();
if(result.Where((t, i) => t != _expectedRandomCrc16Ccitt[i]).Any())
throw new Exception("Invalid hash value");
}
if(result?.Length != _expectedRandomCrc16.Length)
throw new Exception("Invalid hash length");
public static void Crc16()
{
Native.ForceManaged = false;
if(result.Where((t, i) => t != _expectedRandomCrc16[i]).Any())
throw new Exception("Invalid hash value");
}
byte[] data = new byte[1048576];
public static void Crc32()
{
Native.ForceManaged = false;
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
byte[] data = new byte[1048576];
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new CRC16IBMContext();
ctx.Update(data);
byte[] result = ctx.Final();
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
if(result?.Length != _expectedRandomCrc16.Length)
throw new Exception("Invalid hash length");
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc32Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result.Where((t, i) => t != _expectedRandomCrc16[i]).Any())
throw new Exception("Invalid hash value");
}
if(result?.Length != _expectedRandomCrc32.Length)
throw new Exception("Invalid hash length");
public static void Crc32()
{
Native.ForceManaged = false;
if(result.Where((t, i) => t != _expectedRandomCrc32[i]).Any())
throw new Exception("Invalid hash value");
}
byte[] data = new byte[1048576];
public static void Crc64()
{
Native.ForceManaged = false;
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
byte[] data = new byte[1048576];
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc32Context();
ctx.Update(data);
byte[] result = ctx.Final();
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
if(result?.Length != _expectedRandomCrc32.Length)
throw new Exception("Invalid hash length");
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc64Context();
ctx.Update(data);
byte[] result = ctx.Final();
if(result.Where((t, i) => t != _expectedRandomCrc32[i]).Any())
throw new Exception("Invalid hash value");
}
if(result?.Length != _expectedRandomCrc64.Length)
throw new Exception("Invalid hash length");
public static void Crc64()
{
Native.ForceManaged = false;
if(result.Where((t, i) => t != _expectedRandomCrc64[i]).Any())
throw new Exception("Invalid hash value");
}
byte[] data = new byte[1048576];
public static void SpamSum()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[256];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IChecksum ctx = new Crc64Context();
ctx.Update(data);
byte[] result = ctx.Final();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
if(result?.Length != _expectedRandomCrc64.Length)
throw new Exception("Invalid hash length");
IntPtr ctx = spamsum_init();
if(result.Where((t, i) => t != _expectedRandomCrc64[i]).Any())
throw new Exception("Invalid hash value");
}
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
public static void SpamSum()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[256];
int ret = spamsum_update(ctx, data, (uint)data.Length);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
if(ret != 0)
throw new Exception("Could not digest block");
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
ret = spamsum_final(ctx, hash);
IntPtr ctx = spamsum_init();
if(ret != 0)
throw new Exception("Could not finalize block");
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
spamsum_free(ctx);
}
int ret = spamsum_update(ctx, data, (uint)data.Length);
if(ret != 0)
throw new Exception("Could not digest block");
ret = spamsum_final(ctx, hash);
if(ret != 0)
throw new Exception("Could not finalize block");
spamsum_free(ctx);
}
}

View File

@@ -3,245 +3,244 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace AaruBenchmark.Checksums
namespace AaruBenchmark.Checksums;
public class OpenSsl
{
public class OpenSsl
static readonly byte[] _expectedRandomMd5 =
{
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
[DllImport("libssl", SetLastError = true)]
static extern int EVP_DigestInit(IntPtr ctx, IntPtr type);
[DllImport("libssl", SetLastError = true)]
static extern int EVP_DigestInit(IntPtr ctx, IntPtr type);
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_MD_CTX_new();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_MD_CTX_new();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_md5();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_md5();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_sha1();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_sha1();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_sha256();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_sha256();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_sha384();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_sha384();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_sha512();
[DllImport("libssl", SetLastError = true)]
static extern IntPtr EVP_sha512();
[DllImport("libssl", SetLastError = true)]
static extern int EVP_DigestUpdate(IntPtr ctx, byte[] d, ulong cnt);
[DllImport("libssl", SetLastError = true)]
static extern int EVP_DigestUpdate(IntPtr ctx, byte[] d, ulong cnt);
[DllImport("libssl", SetLastError = true)]
static extern int EVP_DigestFinal(IntPtr ctx, byte[] md, ref uint s);
[DllImport("libssl", SetLastError = true)]
static extern int EVP_DigestFinal(IntPtr ctx, byte[] md, ref uint s);
[DllImport("libssl", SetLastError = true)]
static extern void EVP_MD_CTX_free(IntPtr ctx);
[DllImport("libssl", SetLastError = true)]
static extern void EVP_MD_CTX_free(IntPtr ctx);
public static void Md5()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[16];
public static void Md5()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[16];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IntPtr md = EVP_md5();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
IntPtr md = EVP_md5();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
if(ret != 1)
throw new Exception("Could not initialize digest");
if(ret != 1)
throw new Exception("Could not initialize digest");
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
if(ret != 1)
throw new Exception("Could not digest block");
if(ret != 1)
throw new Exception("Could not digest block");
ret = EVP_DigestFinal(ctx, hash, ref s);
ret = EVP_DigestFinal(ctx, hash, ref s);
if(ret != 1)
throw new Exception("Could not finalize hash");
if(ret != 1)
throw new Exception("Could not finalize hash");
EVP_MD_CTX_free(ctx);
EVP_MD_CTX_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomMd5[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomMd5[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha1()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[20];
public static void Sha1()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[20];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IntPtr md = EVP_sha1();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
IntPtr md = EVP_sha1();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
if(ret != 1)
throw new Exception("Could not initialize digest");
if(ret != 1)
throw new Exception("Could not initialize digest");
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
if(ret != 1)
throw new Exception("Could not digest block");
if(ret != 1)
throw new Exception("Could not digest block");
ret = EVP_DigestFinal(ctx, hash, ref s);
ret = EVP_DigestFinal(ctx, hash, ref s);
if(ret != 1)
throw new Exception("Could not finalize hash");
if(ret != 1)
throw new Exception("Could not finalize hash");
EVP_MD_CTX_free(ctx);
EVP_MD_CTX_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomSha1[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomSha1[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha256()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[32];
public static void Sha256()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[32];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IntPtr md = EVP_sha256();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
IntPtr md = EVP_sha256();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
if(ret != 1)
throw new Exception("Could not initialize digest");
if(ret != 1)
throw new Exception("Could not initialize digest");
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
if(ret != 1)
throw new Exception("Could not digest block");
if(ret != 1)
throw new Exception("Could not digest block");
ret = EVP_DigestFinal(ctx, hash, ref s);
ret = EVP_DigestFinal(ctx, hash, ref s);
if(ret != 1)
throw new Exception("Could not finalize hash");
if(ret != 1)
throw new Exception("Could not finalize hash");
EVP_MD_CTX_free(ctx);
EVP_MD_CTX_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomSha256[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomSha256[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha384()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[48];
public static void Sha384()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[48];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IntPtr md = EVP_sha384();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
IntPtr md = EVP_sha384();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
if(ret != 1)
throw new Exception("Could not initialize digest");
if(ret != 1)
throw new Exception("Could not initialize digest");
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
if(ret != 1)
throw new Exception("Could not digest block");
if(ret != 1)
throw new Exception("Could not digest block");
ret = EVP_DigestFinal(ctx, hash, ref s);
ret = EVP_DigestFinal(ctx, hash, ref s);
if(ret != 1)
throw new Exception("Could not finalize hash");
if(ret != 1)
throw new Exception("Could not finalize hash");
EVP_MD_CTX_free(ctx);
EVP_MD_CTX_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomSha384[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomSha384[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha512()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[64];
public static void Sha512()
{
byte[] data = new byte[1048576];
uint s = 0;
byte[] hash = new byte[64];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
IntPtr md = EVP_sha512();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
IntPtr md = EVP_sha512();
IntPtr ctx = EVP_MD_CTX_new();
int ret = EVP_DigestInit(ctx, md);
if(ret != 1)
throw new Exception("Could not initialize digest");
if(ret != 1)
throw new Exception("Could not initialize digest");
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
ret = EVP_DigestUpdate(ctx, data, (ulong)data.Length);
if(ret != 1)
throw new Exception("Could not digest block");
if(ret != 1)
throw new Exception("Could not digest block");
ret = EVP_DigestFinal(ctx, hash, ref s);
ret = EVP_DigestFinal(ctx, hash, ref s);
if(ret != 1)
throw new Exception("Could not finalize hash");
if(ret != 1)
throw new Exception("Could not finalize hash");
EVP_MD_CTX_free(ctx);
EVP_MD_CTX_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomSha512[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomSha512[i]).Any())
throw new Exception("Invalid hash value");
}
}

View File

@@ -3,264 +3,263 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace AaruBenchmark.Checksums
namespace AaruBenchmark.Checksums;
public class RHash
{
public class RHash
const uint RHASH_CRC32 = 0x01;
const uint RHASH_MD5 = 0x04;
const uint RHASH_SHA1 = 0x08;
const uint RHASH_SHA256 = 0x20000;
const uint RHASH_SHA384 = 0x40000;
const uint RHASH_SHA512 = 0x80000;
const uint RHASH_CRC32C = 0x4000000;
static readonly byte[] _expectedRandomCrc32 =
{
const uint RHASH_CRC32 = 0x01;
const uint RHASH_MD5 = 0x04;
const uint RHASH_SHA1 = 0x08;
const uint RHASH_SHA256 = 0x20000;
const uint RHASH_SHA384 = 0x40000;
const uint RHASH_SHA512 = 0x80000;
const uint RHASH_CRC32C = 0x4000000;
static readonly byte[] _expectedRandomCrc32 =
{
0x2b, 0x6e, 0x68, 0x54
};
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
0x2b, 0x6e, 0x68, 0x54
};
static readonly byte[] _expectedRandomMd5 =
{
0xd7, 0x8f, 0x0e, 0xec, 0x41, 0x7b, 0xe3, 0x86, 0x21, 0x9b, 0x21, 0xb7, 0x00, 0x04, 0x4b, 0x95
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha1 =
{
0x72, 0x0d, 0x3b, 0x71, 0x7d, 0xe0, 0xc7, 0x4c, 0x77, 0xdd, 0x9c, 0xaa, 0x9e, 0xba, 0x50, 0x60, 0xdc, 0xbd,
0x28, 0x8d
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha256 =
{
0x4d, 0x1a, 0x6b, 0x8a, 0x54, 0x67, 0x00, 0xc4, 0x8e, 0xda, 0x70, 0xd3, 0x39, 0x1c, 0x8f, 0x15, 0x8a, 0x8d,
0x12, 0xb2, 0x38, 0x92, 0x89, 0x29, 0x50, 0x47, 0x8c, 0x41, 0x8e, 0x25, 0xcc, 0x39
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha384 =
{
0xdb, 0x53, 0x0e, 0x17, 0x9b, 0x81, 0xfe, 0x5f, 0x6d, 0x20, 0x41, 0x04, 0x6e, 0x77, 0xd9, 0x85, 0xf2, 0x85,
0x8a, 0x66, 0xca, 0xd3, 0x8d, 0x1a, 0xd5, 0xac, 0x67, 0xa9, 0x74, 0xe1, 0xef, 0x3f, 0x4d, 0xdf, 0x94, 0x15,
0x2e, 0xac, 0x2e, 0xfe, 0x16, 0x95, 0x81, 0x54, 0xdc, 0x59, 0xd4, 0xc3
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
static readonly byte[] _expectedRandomSha512 =
{
0x6a, 0x0a, 0x18, 0xc2, 0xad, 0xf8, 0x83, 0xac, 0x58, 0xe6, 0x21, 0x96, 0xdb, 0x8d, 0x3d, 0x0e, 0xb9, 0x87,
0xd1, 0x49, 0x24, 0x97, 0xdb, 0x15, 0xb9, 0xfc, 0xcc, 0xb0, 0x36, 0xdf, 0x64, 0xae, 0xdb, 0x3e, 0x82, 0xa0,
0x4d, 0xdc, 0xd1, 0x37, 0x48, 0x92, 0x95, 0x51, 0xf9, 0xdd, 0xab, 0x82, 0xf4, 0x8a, 0x85, 0x3f, 0x9a, 0x01,
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
[DllImport("librhash", SetLastError = true)]
static extern void rhash_library_init();
[DllImport("librhash", SetLastError = true)]
static extern void rhash_library_init();
[DllImport("librhash", SetLastError = true)]
static extern IntPtr rhash_init(uint hash_id);
[DllImport("librhash", SetLastError = true)]
static extern IntPtr rhash_init(uint hash_id);
[DllImport("librhash", SetLastError = true)]
static extern int rhash_update(IntPtr ctx, byte[] message, ulong length);
[DllImport("librhash", SetLastError = true)]
static extern int rhash_update(IntPtr ctx, byte[] message, ulong length);
[DllImport("librhash", SetLastError = true)]
static extern int rhash_final(IntPtr ctx, byte[] first_result);
[DllImport("librhash", SetLastError = true)]
static extern int rhash_final(IntPtr ctx, byte[] first_result);
[DllImport("librhash", SetLastError = true)]
static extern void rhash_free(IntPtr ctx);
[DllImport("librhash", SetLastError = true)]
static extern void rhash_free(IntPtr ctx);
public static void Crc32()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[4];
public static void Crc32()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[4];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_CRC32);
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_CRC32);
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
int ret = rhash_update(ctx, data, (ulong)data.Length);
int ret = rhash_update(ctx, data, (ulong)data.Length);
if(ret != 0)
throw new Exception("Could not digest block");
if(ret != 0)
throw new Exception("Could not digest block");
ret = rhash_final(ctx, hash);
ret = rhash_final(ctx, hash);
if(ret != 0)
throw new Exception("Could not finalize hash");
if(ret != 0)
throw new Exception("Could not finalize hash");
rhash_free(ctx);
rhash_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomCrc32[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomCrc32[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Md5()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[16];
public static void Md5()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[16];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_MD5);
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_MD5);
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
int ret = rhash_update(ctx, data, (ulong)data.Length);
int ret = rhash_update(ctx, data, (ulong)data.Length);
if(ret != 0)
throw new Exception("Could not digest block");
if(ret != 0)
throw new Exception("Could not digest block");
ret = rhash_final(ctx, hash);
ret = rhash_final(ctx, hash);
if(ret != 0)
throw new Exception("Could not finalize hash");
if(ret != 0)
throw new Exception("Could not finalize hash");
rhash_free(ctx);
rhash_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomMd5[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomMd5[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha1()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[20];
public static void Sha1()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[20];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_SHA1);
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_SHA1);
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
int ret = rhash_update(ctx, data, (ulong)data.Length);
int ret = rhash_update(ctx, data, (ulong)data.Length);
if(ret != 0)
throw new Exception("Could not digest block");
if(ret != 0)
throw new Exception("Could not digest block");
ret = rhash_final(ctx, hash);
ret = rhash_final(ctx, hash);
if(ret != 0)
throw new Exception("Could not finalize hash");
if(ret != 0)
throw new Exception("Could not finalize hash");
rhash_free(ctx);
rhash_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomSha1[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomSha1[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha256()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[32];
public static void Sha256()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[32];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_SHA256);
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_SHA256);
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
int ret = rhash_update(ctx, data, (ulong)data.Length);
int ret = rhash_update(ctx, data, (ulong)data.Length);
if(ret != 0)
throw new Exception("Could not digest block");
if(ret != 0)
throw new Exception("Could not digest block");
ret = rhash_final(ctx, hash);
ret = rhash_final(ctx, hash);
if(ret != 0)
throw new Exception("Could not finalize hash");
if(ret != 0)
throw new Exception("Could not finalize hash");
rhash_free(ctx);
rhash_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomSha256[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomSha256[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha384()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[48];
public static void Sha384()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[48];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_SHA384);
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_SHA384);
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
int ret = rhash_update(ctx, data, (ulong)data.Length);
int ret = rhash_update(ctx, data, (ulong)data.Length);
if(ret != 0)
throw new Exception("Could not digest block");
if(ret != 0)
throw new Exception("Could not digest block");
ret = rhash_final(ctx, hash);
ret = rhash_final(ctx, hash);
if(ret != 0)
throw new Exception("Could not finalize hash");
if(ret != 0)
throw new Exception("Could not finalize hash");
rhash_free(ctx);
rhash_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomSha384[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomSha384[i]).Any())
throw new Exception("Invalid hash value");
}
public static void Sha512()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[64];
public static void Sha512()
{
byte[] data = new byte[1048576];
byte[] hash = new byte[64];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_SHA512);
rhash_library_init();
IntPtr ctx = rhash_init(RHASH_SHA512);
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
if(ctx == IntPtr.Zero)
throw new Exception("Could not initialize digest");
int ret = rhash_update(ctx, data, (ulong)data.Length);
int ret = rhash_update(ctx, data, (ulong)data.Length);
if(ret != 0)
throw new Exception("Could not digest block");
if(ret != 0)
throw new Exception("Could not digest block");
ret = rhash_final(ctx, hash);
ret = rhash_final(ctx, hash);
if(ret != 0)
throw new Exception("Could not finalize hash");
if(ret != 0)
throw new Exception("Could not finalize hash");
rhash_free(ctx);
rhash_free(ctx);
if(hash.Where((t, i) => t != _expectedRandomSha512[i]).Any())
throw new Exception("Invalid hash value");
}
if(hash.Where((t, i) => t != _expectedRandomSha512[i]).Any())
throw new Exception("Invalid hash value");
}
}

View File

@@ -4,128 +4,127 @@ using Aaru6.Checksums;
using CUETools.Codecs;
using CUETools.Codecs.Flake;
namespace AaruBenchmark.Compression
namespace AaruBenchmark.Compression;
public class Aaru
{
public class Aaru
public static void AppleRle()
{
public static void AppleRle()
const int bufferSize = 20960;
byte[] input = new byte[1102];
var fs = new FileStream(Path.Combine(Program.Folder, "apple_rle.bin"), FileMode.Open, FileAccess.Read);
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
byte[] output = new byte[bufferSize];
var rle = new AppleRle(new MemoryStream(input));
for(int i = 0; i < bufferSize; i++)
output[i] = (byte)rle.ProduceByte();
string crc = Crc32Context.Data(output, out _);
if(crc != "3525ef06")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void TeleDiskLzh()
{
const int bufsz = 512;
byte[] input = new byte[9040];
var fs = new FileStream(Path.Combine(Program.Folder, "teledisk_lzh.bin"), FileMode.Open, FileAccess.Read);
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
int rd;
int total_rd = 0;
var lzh = new TeleDiskLzh(new MemoryStream(input));
var outMs = new MemoryStream();
do
{
const int bufferSize = 20960;
if((rd = lzh.Decode(out byte[] obuf, bufsz)) > 0)
outMs.Write(obuf, 0, rd);
byte[] input = new byte[1102];
total_rd += rd;
} while(rd == bufsz);
var fs = new FileStream(Path.Combine(Program.Folder, "apple_rle.bin"), FileMode.Open, FileAccess.Read);
byte[] output = outMs.ToArray();
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
if(total_rd != 39820)
throw new InvalidDataException("Incorrect decompressed data");
byte[] output = new byte[bufferSize];
if(output.Length != 39820)
throw new InvalidDataException("Incorrect decompressed data");
var rle = new AppleRle(new MemoryStream(input));
string crc = Crc32Context.Data(output, out _);
for(int i = 0; i < bufferSize; i++)
output[i] = (byte)rle.ProduceByte();
if(crc != "22bd5d44")
throw new InvalidDataException("Incorrect decompressed checksum");
}
string crc = Crc32Context.Data(output, out _);
public static void Flac()
{
var flacMs = new FileStream(Path.Combine(Program.Folder, "flac.flac"), FileMode.Open, FileAccess.Read);
var flakeReader = new AudioDecoder(new DecoderSettings(), "", flacMs);
byte[] block = new byte[9633792];
int samples = block.Length / 2352 * 588;
var audioBuffer = new AudioBuffer(AudioPCMConfig.RedBook, block, samples);
flakeReader.Read(audioBuffer, samples);
flakeReader.Close();
flacMs.Close();
if(crc != "3525ef06")
throw new InvalidDataException("Incorrect decompressed checksum");
}
string crc = Crc32Context.Data(block, out _);
public static void TeleDiskLzh()
if(crc != "dfbc99bb")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void CompressFlac()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "audio.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[9633792];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[9633792];
var flakeWriterSettings = new EncoderSettings
{
const int bufsz = 512;
PCM = AudioPCMConfig.RedBook,
DoMD5 = false,
BlockSize = 4608,
MinFixedOrder = 0,
MaxFixedOrder = 4,
MinLPCOrder = 1,
MaxLPCOrder = 32,
MaxPartitionOrder = 8,
StereoMethod = StereoMethod.Evaluate,
PredictionType = PredictionType.Search,
WindowMethod = WindowMethod.EvaluateN,
EstimationDepth = 5,
MinPrecisionSearch = 1,
MaxPrecisionSearch = 1,
TukeyParts = 0,
TukeyOverlap = 1.0,
TukeyP = 1.0,
AllowNonSubset = true
};
byte[] input = new byte[9040];
var fs = new FileStream(Path.Combine(Program.Folder, "teledisk_lzh.bin"), FileMode.Open, FileAccess.Read);
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
int rd;
int total_rd = 0;
var lzh = new TeleDiskLzh(new MemoryStream(input));
var outMs = new MemoryStream();
do
{
if((rd = lzh.Decode(out byte[] obuf, bufsz)) > 0)
outMs.Write(obuf, 0, rd);
total_rd += rd;
} while(rd == bufsz);
byte[] output = outMs.ToArray();
if(total_rd != 39820)
throw new InvalidDataException("Incorrect decompressed data");
if(output.Length != 39820)
throw new InvalidDataException("Incorrect decompressed data");
string crc = Crc32Context.Data(output, out _);
if(crc != "22bd5d44")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void Flac()
var flakeWriter = new AudioEncoder(flakeWriterSettings, "", new MemoryStream(backendBuffer))
{
var flacMs = new FileStream(Path.Combine(Program.Folder, "flac.flac"), FileMode.Open, FileAccess.Read);
var flakeReader = new AudioDecoder(new DecoderSettings(), "", flacMs);
byte[] block = new byte[9633792];
int samples = block.Length / 2352 * 588;
var audioBuffer = new AudioBuffer(AudioPCMConfig.RedBook, block, samples);
flakeReader.Read(audioBuffer, samples);
flakeReader.Close();
flacMs.Close();
DoSeekTable = false
};
string crc = Crc32Context.Data(block, out _);
if(crc != "dfbc99bb")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void CompressFlac()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "audio.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[9633792];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[9633792];
var flakeWriterSettings = new EncoderSettings
{
PCM = AudioPCMConfig.RedBook,
DoMD5 = false,
BlockSize = 4608,
MinFixedOrder = 0,
MaxFixedOrder = 4,
MinLPCOrder = 1,
MaxLPCOrder = 32,
MaxPartitionOrder = 8,
StereoMethod = StereoMethod.Evaluate,
PredictionType = PredictionType.Search,
WindowMethod = WindowMethod.EvaluateN,
EstimationDepth = 5,
MinPrecisionSearch = 1,
MaxPrecisionSearch = 1,
TukeyParts = 0,
TukeyOverlap = 1.0,
TukeyP = 1.0,
AllowNonSubset = true
};
var flakeWriter = new AudioEncoder(flakeWriterSettings, "", new MemoryStream(backendBuffer))
{
DoSeekTable = false
};
var audioBuffer = new AudioBuffer(AudioPCMConfig.RedBook, decompressed, 2408448);
flakeWriter.Write(audioBuffer);
}
var audioBuffer = new AudioBuffer(AudioPCMConfig.RedBook, decompressed, 2408448);
flakeWriter.Write(audioBuffer);
}
}

View File

@@ -2,95 +2,94 @@ using System.IO;
using Aaru6.Checksums;
using Aaru6.Compression;
namespace AaruBenchmark.Compression
namespace AaruBenchmark.Compression;
public class Aaru6Compressions
{
public class Aaru6Compressions
public static void AppleRle()
{
public static void AppleRle()
const int bufferSize = 32768;
byte[] input = new byte[1102];
var fs = new FileStream(Path.Combine(Program.Folder, "apple_rle.bin"), FileMode.Open, FileAccess.Read);
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
byte[] output = new byte[bufferSize];
int realSize = Aaru6.Compression.AppleRle.DecodeBuffer(input, output);
if(realSize != 20960)
throw new InvalidDataException("Incorrect decompressed size");
string crc = Crc32Context.Data(output, (uint)realSize, out _);
if(crc != "3525ef06")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void TeleDiskLzh()
{
const int bufsz = 512;
byte[] input = new byte[9040];
var fs = new FileStream(Path.Combine(Program.Folder, "teledisk_lzh.bin"), FileMode.Open, FileAccess.Read);
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
int rd;
int total_rd = 0;
var lzh = new TeleDiskLzh(new MemoryStream(input));
var outMs = new MemoryStream();
do
{
const int bufferSize = 32768;
byte[] input = new byte[1102];
if((rd = lzh.Decode(out byte[] obuf, bufsz)) > 0)
outMs.Write(obuf, 0, rd);
var fs = new FileStream(Path.Combine(Program.Folder, "apple_rle.bin"), FileMode.Open, FileAccess.Read);
total_rd += rd;
} while(rd == bufsz);
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
byte[] output = outMs.ToArray();
byte[] output = new byte[bufferSize];
if(total_rd != 39820)
throw new InvalidDataException("Incorrect decompressed data");
int realSize = Aaru6.Compression.AppleRle.DecodeBuffer(input, output);
if(output.Length != 39820)
throw new InvalidDataException("Incorrect decompressed data");
if(realSize != 20960)
throw new InvalidDataException("Incorrect decompressed size");
string crc = Crc32Context.Data(output, out _);
string crc = Crc32Context.Data(output, (uint)realSize, out _);
if(crc != "22bd5d44")
throw new InvalidDataException("Incorrect decompressed checksum");
}
if(crc != "3525ef06")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void ADC()
{
const int bufferSize = 262144;
byte[] input = new byte[34367];
public static void TeleDiskLzh()
{
const int bufsz = 512;
var fs = new FileStream(Path.Combine(Program.Folder, "adc.bin"), FileMode.Open, FileAccess.Read);
byte[] input = new byte[9040];
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
var fs = new FileStream(Path.Combine(Program.Folder, "teledisk_lzh.bin"), FileMode.Open, FileAccess.Read);
byte[] output = new byte[bufferSize];
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
int realSize = Aaru6.Compression.ADC.DecodeBuffer(input, output);
int rd;
int total_rd = 0;
var lzh = new TeleDiskLzh(new MemoryStream(input));
var outMs = new MemoryStream();
if(realSize != 262144)
throw new InvalidDataException("Incorrect decompressed size");
do
{
if((rd = lzh.Decode(out byte[] obuf, bufsz)) > 0)
outMs.Write(obuf, 0, rd);
string crc = Crc32Context.Data(output, (uint)realSize, out _);
total_rd += rd;
} while(rd == bufsz);
byte[] output = outMs.ToArray();
if(total_rd != 39820)
throw new InvalidDataException("Incorrect decompressed data");
if(output.Length != 39820)
throw new InvalidDataException("Incorrect decompressed data");
string crc = Crc32Context.Data(output, out _);
if(crc != "22bd5d44")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void ADC()
{
const int bufferSize = 262144;
byte[] input = new byte[34367];
var fs = new FileStream(Path.Combine(Program.Folder, "adc.bin"), FileMode.Open, FileAccess.Read);
fs.Read(input, 0, input.Length);
fs.Close();
fs.Dispose();
byte[] output = new byte[bufferSize];
int realSize = Aaru6.Compression.ADC.DecodeBuffer(input, output);
if(realSize != 262144)
throw new InvalidDataException("Incorrect decompressed size");
string crc = Crc32Context.Data(output, (uint)realSize, out _);
if(crc != "5a5a7388")
throw new InvalidDataException("Incorrect decompressed checksum");
}
if(crc != "5a5a7388")
throw new InvalidDataException("Incorrect decompressed checksum");
}
}

View File

@@ -2,160 +2,159 @@ using System.IO;
using Ionic.BZip2;
using Ionic.Zlib;
namespace AaruBenchmark.Compression
namespace AaruBenchmark.Compression;
public static class DotNetZip
{
public static class DotNetZip
public static void Gzip()
{
public static void Gzip()
var _dataStream = new FileStream(Path.Combine(Program.Folder, "gzip.gz"), FileMode.Open, FileAccess.Read);
Stream str = new GZipStream(_dataStream, CompressionMode.Decompress, true);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
while(left > 0)
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "gzip.gz"), FileMode.Open, FileAccess.Read);
Stream str = new GZipStream(_dataStream, CompressionMode.Decompress, true);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
int done = str.Read(compressed, pos, left);
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
left -= done;
pos += done;
}
public static void CompressGzip()
str.Close();
str.Dispose();
}
public static void CompressGzip()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
var cmpMs = new MemoryStream();
Stream cmpStream = new GZipStream(cmpMs, CompressionMode.Compress, true);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
cmpMs.Position = 0;
/* This is just to test integrity, disabled for benchmarking
Stream str = new GZipStream(cmpMs, CompressionMode.Decompress, true);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
int done = str.Read(compressed, pos, left);
var cmpMs = new MemoryStream();
Stream cmpStream = new GZipStream(cmpMs, CompressionMode.Compress, true);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
cmpMs.Position = 0;
/* This is just to test integrity, disabled for benchmarking
Stream str = new GZipStream(cmpMs, CompressionMode.Decompress, true);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
left -= done;
pos += done;
}
public static void Bzip2()
str.Close();
str.Dispose();
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
}
public static void Bzip2()
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "bzip2.bz2"), FileMode.Open, FileAccess.Read);
Stream str = new BZip2InputStream(_dataStream, true);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
while(left > 0)
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "bzip2.bz2"), FileMode.Open, FileAccess.Read);
Stream str = new BZip2InputStream(_dataStream, true);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
int done = str.Read(compressed, pos, left);
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
left -= done;
pos += done;
}
public static void CompressBzip2()
str.Close();
str.Dispose();
}
public static void CompressBzip2()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
var cmpMs = new MemoryStream();
Stream cmpStream = new BZip2OutputStream(cmpMs, 9, true);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
cmpMs.Position = 0;
/* This is just to test integrity, disabled for benchmarking
Stream str = new BZip2InputStream(cmpMs, true);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
int done = str.Read(compressed, pos, left);
var cmpMs = new MemoryStream();
Stream cmpStream = new BZip2OutputStream(cmpMs, 9, true);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
cmpMs.Position = 0;
/* This is just to test integrity, disabled for benchmarking
Stream str = new BZip2InputStream(cmpMs, true);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
left -= done;
pos += done;
}
str.Close();
str.Dispose();
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
}
}

View File

@@ -1,84 +1,83 @@
using System.IO;
using System.IO.Compression;
namespace AaruBenchmark.Compression
namespace AaruBenchmark.Compression;
public static class NetRuntime
{
public static class NetRuntime
public static void Gzip()
{
public static void Gzip()
var _dataStream = new FileStream(Path.Combine(Program.Folder, "gzip.gz"), FileMode.Open, FileAccess.Read);
Stream str = new GZipStream(_dataStream, CompressionMode.Decompress, true);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
while(left > 0)
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "gzip.gz"), FileMode.Open, FileAccess.Read);
Stream str = new GZipStream(_dataStream, CompressionMode.Decompress, true);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
int done = str.Read(compressed, pos, left);
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
left -= done;
pos += done;
}
public static void CompressGzip()
str.Close();
str.Dispose();
}
public static void CompressGzip()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
var cmpMs = new MemoryStream();
Stream cmpStream = new GZipStream(cmpMs, CompressionMode.Compress, true);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
cmpMs.Position = 0;
/* This is just to test integrity, disabled for benchmarking
Stream str = new GZipStream(cmpMs, CompressionMode.Decompress, true);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
int done = str.Read(compressed, pos, left);
var cmpMs = new MemoryStream();
Stream cmpStream = new GZipStream(cmpMs, CompressionMode.Compress, true);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
cmpMs.Position = 0;
/* This is just to test integrity, disabled for benchmarking
Stream str = new GZipStream(cmpMs, CompressionMode.Decompress, true);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
left -= done;
pos += done;
}
str.Close();
str.Dispose();
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
}
}

View File

@@ -6,348 +6,347 @@ using SharpCompress.Compressors.BZip2;
using SharpCompress.Compressors.Deflate;
using SharpCompress.Compressors.LZMA;
namespace AaruBenchmark.Compression
namespace AaruBenchmark.Compression;
public static class SharpCompress
{
public static class SharpCompress
public static void Gzip()
{
public static void Gzip()
var _dataStream = new FileStream(Path.Combine(Program.Folder, "gzip.gz"), FileMode.Open, FileAccess.Read);
Stream str = new GZipStream(_dataStream, CompressionMode.Decompress);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
while(left > 0)
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "gzip.gz"), FileMode.Open, FileAccess.Read);
Stream str = new GZipStream(_dataStream, CompressionMode.Decompress);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
int done = str.Read(compressed, pos, left);
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
left -= done;
pos += done;
}
public static void CompressGzip()
str.Close();
str.Dispose();
}
public static void CompressGzip()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[8388608];
Stream cmpStream = new GZipStream(new MemoryStream(backendBuffer), CompressionMode.Compress,
CompressionLevel.Level9);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
/* This is just to test integrity, disabled for benchmarking
Stream str = new GZipStream(new MemoryStream(backendBuffer), CompressionMode.Decompress);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[8388608];
int done = str.Read(compressed, pos, left);
Stream cmpStream = new GZipStream(new MemoryStream(backendBuffer), CompressionMode.Compress,
CompressionLevel.Level9);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
/* This is just to test integrity, disabled for benchmarking
Stream str = new GZipStream(new MemoryStream(backendBuffer), CompressionMode.Decompress);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
left -= done;
pos += done;
}
public static void Bzip2()
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
}
public static void Bzip2()
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "bzip2.bz2"), FileMode.Open, FileAccess.Read);
Stream str = new BZip2Stream(_dataStream, CompressionMode.Decompress, true);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
while(left > 0)
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "bzip2.bz2"), FileMode.Open, FileAccess.Read);
Stream str = new BZip2Stream(_dataStream, CompressionMode.Decompress, true);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
int done = str.Read(compressed, pos, left);
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
left -= done;
pos += done;
}
public static void CompressBzip2()
str.Close();
str.Dispose();
}
public static void CompressBzip2()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[8388608];
Stream cmpStream = new BZip2Stream(new MemoryStream(backendBuffer), CompressionMode.Compress, true);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
/* This is just to test integrity, disabled for benchmarking
Stream str = new BZip2Stream(new MemoryStream(backendBuffer), CompressionMode.Decompress, false);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[8388608];
int done = str.Read(compressed, pos, left);
Stream cmpStream = new BZip2Stream(new MemoryStream(backendBuffer), CompressionMode.Compress, true);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
/* This is just to test integrity, disabled for benchmarking
Stream str = new BZip2Stream(new MemoryStream(backendBuffer), CompressionMode.Decompress, false);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
left -= done;
pos += done;
}
public static void ADC()
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
}
public static void ADC()
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "adc.bin"), FileMode.Open, FileAccess.Read);
Stream str = new ADCStream(_dataStream);
byte[] compressed = new byte[262144];
int pos = 0;
int left = 262144;
bool oneZero = false;
while(left > 0)
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "adc.bin"), FileMode.Open, FileAccess.Read);
Stream str = new ADCStream(_dataStream);
byte[] compressed = new byte[262144];
int pos = 0;
int left = 262144;
bool oneZero = false;
int done = str.Read(compressed, pos, left);
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
string crc = Crc32Context.Data(compressed, 262144, out _);
if(crc != "5a5a7388")
throw new InvalidDataException("Incorrect decompressed checksum");
left -= done;
pos += done;
}
public static void Lzip()
str.Close();
str.Dispose();
string crc = Crc32Context.Data(compressed, 262144, out _);
if(crc != "5a5a7388")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void Lzip()
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "lzip.lz"), FileMode.Open, FileAccess.Read);
Stream str = new LZipStream(_dataStream, CompressionMode.Decompress);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
while(left > 0)
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "lzip.lz"), FileMode.Open, FileAccess.Read);
Stream str = new LZipStream(_dataStream, CompressionMode.Decompress);
byte[] compressed = new byte[1048576];
int pos = 0;
int left = 1048576;
bool oneZero = false;
int done = str.Read(compressed, pos, left);
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
string crc = Crc32Context.Data(compressed, 1048576, out _);
if(crc != "c64059c0")
throw new InvalidDataException("Incorrect decompressed checksum");
left -= done;
pos += done;
}
public static void CompressLzip()
str.Close();
str.Dispose();
string crc = Crc32Context.Data(compressed, 1048576, out _);
if(crc != "c64059c0")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void CompressLzip()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[8388608];
Stream cmpStream = new LZipStream(new MemoryStream(backendBuffer), CompressionMode.Compress);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
/* This is just to test integrity, disabled for benchmarking
Stream str = new LZipStream(new MemoryStream(backendBuffer), CompressionMode.Decompress);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[8388608];
int done = str.Read(compressed, pos, left);
Stream cmpStream = new LZipStream(new MemoryStream(backendBuffer), CompressionMode.Compress);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
/* This is just to test integrity, disabled for benchmarking
Stream str = new LZipStream(new MemoryStream(backendBuffer), CompressionMode.Decompress);
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
left -= done;
pos += done;
}
public static void Lzma()
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
}
public static void Lzma()
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "lzma.bin"), FileMode.Open, FileAccess.Read);
Stream str = new LzmaStream(new byte[]
{
var _dataStream = new FileStream(Path.Combine(Program.Folder, "lzma.bin"), FileMode.Open, FileAccess.Read);
0x5D, 0x00, 0x00, 0x00, 0x02
}, _dataStream);
Stream str = new LzmaStream(new byte[]
byte[] compressed = new byte[8388608];
int pos = 0;
int left = 8388608;
bool oneZero = false;
while(left > 0)
{
int done = str.Read(compressed, pos, left);
if(done == 0)
{
0x5D, 0x00, 0x00, 0x00, 0x02
}, _dataStream);
if(oneZero)
throw new IOException("Could not read the file!");
byte[] compressed = new byte[8388608];
int pos = 0;
int left = 8388608;
bool oneZero = false;
while(left > 0)
{
int done = str.Read(compressed, pos, left);
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
str.Close();
str.Dispose();
string crc = Crc32Context.Data(compressed, 8388608, out _);
if(crc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
left -= done;
pos += done;
}
public static void CompressLzma()
str.Close();
str.Dispose();
string crc = Crc32Context.Data(compressed, 8388608, out _);
if(crc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
}
public static void CompressLzma()
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[8388608];
var cmpStream = new LzmaStream(new LzmaEncoderProperties(true, 1048576, 273), false,
new MemoryStream(backendBuffer));
byte[] propertiesArray = new byte[cmpStream.Properties.Length];
cmpStream.Properties.CopyTo(propertiesArray, 0);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
/* This is just to test integrity, disabled for benchmarking
Stream str = new LzmaStream(propertiesArray, new MemoryStream(backendBuffer));
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
{
var dataStream = new FileStream(Path.Combine(Program.Folder, "data.bin"), FileMode.Open, FileAccess.Read);
byte[] decompressed = new byte[8388608];
dataStream.Read(decompressed, 0, decompressed.Length);
dataStream.Close();
byte[] backendBuffer = new byte[8388608];
int done = str.Read(compressed, pos, left);
var cmpStream = new LzmaStream(new LzmaEncoderProperties(true, 1048576, 273), false,
new MemoryStream(backendBuffer));
byte[] propertiesArray = new byte[cmpStream.Properties.Length];
cmpStream.Properties.CopyTo(propertiesArray, 0);
cmpStream.Write(decompressed, 0, decompressed.Length);
cmpStream.Close();
/* This is just to test integrity, disabled for benchmarking
Stream str = new LzmaStream(propertiesArray, new MemoryStream(backendBuffer));
byte[] compressed = new byte[decompressed.Length];
int pos = 0;
int left = compressed.Length;
bool oneZero = false;
while(left > 0)
if(done == 0)
{
int done = str.Read(compressed, pos, left);
if(oneZero)
throw new IOException("Could not read the file!");
if(done == 0)
{
if(oneZero)
throw new IOException("Could not read the file!");
oneZero = true;
}
left -= done;
pos += done;
oneZero = true;
}
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
left -= done;
pos += done;
}
string newCrc = Crc32Context.Data(compressed, (uint)compressed.Length, out _);
if(newCrc != "954bf76e")
throw new InvalidDataException("Incorrect decompressed checksum");
*/
}
}

View File

@@ -5,7 +5,7 @@ using BenchmarkDotNet.Running;
namespace AaruBenchmark;
internal static class Program
static class Program
{
internal static string Folder => Path.Combine(Environment.CurrentDirectory, "data");

Binary file not shown.