Crc64
Provides an implementation of the CRC-64 algorithm as described in ECMA-182, Annex B.
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
namespace System.IO.Hashing
{
public sealed class Crc64 : NonCryptographicHashAlgorithm
{
private const ulong InitialState = 0;
private const int Size = 8;
private ulong _crc;
private static ReadOnlySpan<ulong> CrcLookup {
get {
object obj = global::<PrivateImplementationDetails>.9510833BE85D6E7BDB0A990BB21B3E1C205A015F87BC5382489CDAF427C2AA8B_A15;
if (obj == null) {
obj = new ulong[256] {
0,
4823603603198064275,
9647207206396128550,
14344283933443513269,
5274672035359026399,
847670339082705484,
14759040976900489721,
10241823793177474922,
10549344070718052798,
15030250704074698541,
1695340678165410968,
6158653484774949387,
15804726273676621153,
11071337880091427826,
6824194888265062471,
2036903512645398228,
7367177604490692079,
2651944067726553980,
16419204125234161865,
11613757334439845466,
3390681356330821936,
7926053118503640995,
12317306969549898774,
16726154088988619397,
17607865585094646865,
13162708473643690690,
8194994013375312247,
3695931686473304036,
13648389776530124942,
18417527692557321757,
4073807025290796456,
8825348881154370363,
14734355208981384158,
10271039580541631821,
5303888135453107960,
822984195088142443,
9604374506261047041,
14391664176758772114,
47380625301539367,
4780770595170139316,
6781362712661643872,
2084283301222999283,
15852106237007281990,
11028505464239851989,
1670654249350217407,
6187869865390245932,
10578560694269006745,
15005564104267687178,
12269926345859042865,
16768987096479742114,
3433514057002836759,
7878672873577829764,
16389988026750624494,
11638443477897467005,
7391863372946608072,
2622728278751721819,
4044590402276644751,
8850035479350698268,
13673076206955870889,
18388311311405091898,
8147614050581592912,
3738764100714335683,
17650697762308740726,
13115328684529279205,
15709965168302367023,
11021966344253216700,
6909860770376862729,
2095335087373712026,
10607776270906215920,
15115916238825782115,
1645968390176284886,
6063892853452478021,
5216239979862816913,
762004938812542466,
14808413130408695223,
10336584279807992612,
94761250603078734,
4872975272980325085,
9561541190340278632,
14285852213486374907,
13562725425323287744,
18359094313119879763,
4168566602445998566,
8874722219015798645,
17657238303940757535,
13257468400305012364,
8136561383943382329,
3610266854770152362,
3341308498700434814,
7831293060043656173,
12375739730780491864,
16811819059476047563,
7452841817450123681,
2710377314828461874,
16324444680414493831,
11564384134825822740,
1621282580641819377,
6093108618008534114,
10636992411005044695,
15091230119249932612,
6867028114005673518,
2142715359940571325,
15757345747155659528,
10979133309658045851,
9518708972583580495,
14333231979791697372,
142141253402664553,
4830142882085382394,
14783726745893216144,
10365800689136969987,
5245456557503443638,
737318311902463013,
8089180804553289502,
3653099890976004493,
17700070958701396536,
13210088128275084459,
4139350461810230209,
8899408340202190162,
13587411233247080167,
18329878549100632180,
16295228101163185824,
11589070762272702515,
7477528201428671366,
2681160907110034709,
12328359726370364031,
16854651450907929836,
3384140715920324441,
7783913295349006794,
17796789492404876493,
12973186262895182430,
8294265019745835499,
3597188614796881784,
13819721540753725458,
18246723593521770113,
4190670174747424052,
8707887697765516199,
7249714899603402099,
2768808468102880224,
16248400991498780757,
11785088403942012614,
3291936780352569772,
8025325358597240639,
12127785706904956042,
16915077318774037017,
10432479959725633826,
15147713122803500977,
1524009877625084932,
6329456346323069591,
15705454305770282493,
11170082187107838830,
6635271944638132443,
2226424485906433608,
189522501206157468,
4634679410803088911,
9745950545960650170,
14245012653811987241,
5445476407655580739,
676338306971005648,
14876502445374089573,
10124960353263198198,
4215391513593610003,
8678706776937023872,
13790540925671641653,
18271444552530207910,
8337133204891997132,
3549843186494580063,
17749444438031597290,
13016054137459951737,
12170653315997410989,
16867732534171963454,
3244592164593781643,
8068192726900473112,
16273122767886764658,
11755906975779290337,
7220533709540304724,
2793530071884239303,
6682616997400869628,
2183556611878603887,
15662586120087312346,
11217427617020813641,
1553190491096487459,
6304735387851432112,
10407758620342516485,
15176894045242543510,
14905683634900247362,
10100238751092381137,
5420754629656923748,
705519735670536439,
9793295161182637981,
14202145287119436046,
146654890503152315,
4682024195942093864,
3242565161283638754,
7930564333232481137,
12186217236017068228,
17000743249723264599,
7335380351123765565,
2827240748300537774,
16153640314560107547,
11735716164790313608,
13734056228011347036,
18188291445129067215,
4285430719881142650,
8757259798139230185,
17846161249714921603,
13067947420601767440,
8235833358291897765,
3511522545606540086,
5387043107155988493,
590673871457609374,
14925875833148783915,
10219719885873843128,
284282506805329106,
4684052045342640705,
9660285764170764788,
14186579979835500391,
15610694155489642931,
11120709418076880672,
6720936860919424149,
2284857304564388358,
10490913115006887276,
15233377424362361855,
1474636623804926026,
6234696958930763481,
16178361609106579004,
11706535215248140463,
7306199781952008986,
2851961734412043657,
12229085463316509411,
16953397843693241456,
3195220067441434565,
7973432182840617302,
8278700923620460418,
3464177731752866065,
17798816680404380324,
13110814815472245815,
4310152537884486493,
8728078392784608718,
13704874997943502459,
18213013024491712744,
9707630858549910483,
14143712128616820032,
241414281116563189,
4731397450835853414,
14955056402857342732,
10194998898151653791,
5362321814220069418,
619854820462849209,
1503817855483314797,
6209975379031176446,
10466191297540353867,
15262558828106308056,
6768281431840648882,
2241989909157107745,
15567826590698013588,
11168054230320002311
};
global::<PrivateImplementationDetails>.9510833BE85D6E7BDB0A990BB21B3E1C205A015F87BC5382489CDAF427C2AA8B_A15 = (ulong[])obj;
}
return new ReadOnlySpan<ulong>((ulong[])obj);
}
}
public Crc64()
: base(8)
{
}
private Crc64(ulong crc)
: base(8)
{
_crc = crc;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public Crc64 Clone()
{
return new Crc64(_crc);
}
public override void Append(ReadOnlySpan<byte> source)
{
_crc = Update(_crc, source);
}
public override void Reset()
{
_crc = 0;
}
protected override void GetCurrentHashCore(Span<byte> destination)
{
BinaryPrimitives.WriteUInt64BigEndian(destination, _crc);
}
protected override void GetHashAndResetCore(Span<byte> destination)
{
BinaryPrimitives.WriteUInt64BigEndian(destination, _crc);
_crc = 0;
}
[CLSCompliant(false)]
public ulong GetCurrentHashAsUInt64()
{
return _crc;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static byte[] Hash(byte[] source)
{
ExceptionPolyfills.ThrowIfNull(source, "source");
return Hash(new ReadOnlySpan<byte>(source));
}
[return: System.Runtime.CompilerServices.Nullable(1)]
public static byte[] Hash(ReadOnlySpan<byte> source)
{
byte[] obj = new byte[8];
BinaryPrimitives.WriteUInt64BigEndian(value: HashToUInt64(source), destination: obj);
return obj;
}
public static bool TryHash(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten)
{
if (destination.Length < 8) {
bytesWritten = 0;
return false;
}
ulong value = HashToUInt64(source);
BinaryPrimitives.WriteUInt64BigEndian(destination, value);
bytesWritten = 8;
return true;
}
public static int Hash(ReadOnlySpan<byte> source, Span<byte> destination)
{
if (destination.Length < 8)
NonCryptographicHashAlgorithm.ThrowDestinationTooShort();
ulong value = HashToUInt64(source);
BinaryPrimitives.WriteUInt64BigEndian(destination, value);
return 8;
}
[CLSCompliant(false)]
public static ulong HashToUInt64(ReadOnlySpan<byte> source)
{
return Update(0, source);
}
private static ulong Update(ulong crc, ReadOnlySpan<byte> source)
{
return UpdateScalar(crc, source);
}
private static ulong UpdateScalar(ulong crc, ReadOnlySpan<byte> source)
{
ReadOnlySpan<ulong> crcLookup = CrcLookup;
for (int i = 0; i < source.Length; i++) {
ulong num = crc >> 56;
num ^= source[i];
crc = (crcLookup[(int)num] ^ (crc << 8));
}
return crc;
}
}
}