private void Body(byte[] data, int start, int length) { int remainder = length & 15; int alignedLength = start + (length - remainder); for (int i = start; i < alignedLength; i += 16) { uint k1 = data.ToUInt32(i), k2 = data.ToUInt32(i + 4), k3 = data.ToUInt32(i + 8), k4 = data.ToUInt32(i + 12); H1 ^= (k1 * C1).RotateLeft(15) * C2; H1 = (H1.RotateLeft(19) + H2) * 5 + 0x561ccd1b; H2 ^= (k2 * C2).RotateLeft(16) * C3; H2 = (H2.RotateLeft(17) + H3) * 5 + 0x0bcaa747; H3 ^= (k3 * C3).RotateLeft(17) * C4; H3 = (H3.RotateLeft(15) + H4) * 5 + 0x96cd1c35; H4 ^= (k4 * C4).RotateLeft(18) * C1; H4 = (H4.RotateLeft(13) + H1) * 5 + 0x32ac3b17; } if (remainder > 0) { Tail(data, alignedLength, remainder); } }
private void Body(byte[] data, int start, int length) { int remainder = length & 15; int blocks = length / 16; unsafe { fixed(byte *d = &data[start]) { ulong *current = (ulong *)d; while (blocks-- > 0) { // a variant of original algorithm optimized for processor instruction pipelining H1 ^= (*current++ *C1).RotateLeft(31) * C2; H1 = (H1.RotateLeft(27) + H2) * 5 + 0x52dce729; H2 ^= (*current++ *C2).RotateLeft(33) * C1; H2 = (H2.RotateLeft(31) + H1) * 5 + 0x38495ab5; } if (remainder > 0) { Tail(d + (length - remainder), remainder); } } } }
private void Body(ReadOnlySpan <byte> source) { if (source.Length == 0) { return; } var remainder = source.Length & 15; var blocks = 2 * (source.Length / 16); if (blocks > 0) { var ulongSource = MemoryMarshal.Cast <byte, ulong>(source); for (var block = 0; block < blocks;) { H1 ^= (ulongSource[block++] * C1).RotateLeft(31) * C2; H1 = ((H1.RotateLeft(27) + H2) * 5) + 0x52dce729; H2 ^= (ulongSource[block++] * C2).RotateLeft(33) * C1; H2 = ((H2.RotateLeft(31) + H1) * 5) + 0x38495ab5; } } if (remainder > 0) { Tail(source.Slice(8 * blocks)); } }
private void Body(byte[] data, int start, int length) { int remainder = length & 15; int alignedLength = start + (length - remainder); for (int i = start; i < alignedLength; i += 16) { H1 ^= (data.ToUInt64(i) * C1).RotateLeft(31) * C2; H1 = (H1.RotateLeft(27) + H2) * 5 + 0x52dce729; H2 ^= (data.ToUInt64(i + 8) * C2).RotateLeft(33) * C1; H2 = (H2.RotateLeft(31) + H1) * 5 + 0x38495ab5; } if (remainder > 0) { Tail(data, alignedLength, remainder); } }
private void Body(byte[] data, int start, int length) { if (length == 0) { return; } int remainder = length & 15; int blocks = length / 16; unsafe { fixed(byte *d = &data[start]) { // grab a reference to blocks uint *b = (uint *)d; while (blocks-- > 0) { // K1 - consume first integer H1 ^= (*b++ *C1).RotateLeft(15) * C2; H1 = (H1.RotateLeft(19) + H2) * 5 + 0x561ccd1b; // K2 - consume second integer H2 ^= (*b++ *C2).RotateLeft(16) * C3; H2 = (H2.RotateLeft(17) + H3) * 5 + 0x0bcaa747; // K3 - consume third integer H3 ^= (*b++ *C3).RotateLeft(17) * C4; H3 = (H3.RotateLeft(15) + H4) * 5 + 0x96cd1c35; // K4 - consume fourth integer H4 ^= (*b++ *C4).RotateLeft(18) * C1; H4 = (H4.RotateLeft(13) + H1) * 5 + 0x32ac3b17; } if (remainder > 0) { Tail(d + (length - remainder), remainder); } } } }
private void Body(ReadOnlySpan <byte> source) { if (source.Length == 0) { return; } var remainder = source.Length & 15; var blocks = 4 * (source.Length / 16); if (blocks > 0) { var uintSource = MemoryMarshal.Cast <byte, uint>(source); var block = 0; while (block < blocks) { var k1 = uintSource[block++]; var k2 = uintSource[block++]; var k3 = uintSource[block++]; var k4 = uintSource[block++]; H1 ^= (k1 * C1).RotateLeft(15) * C2; H1 = ((H1.RotateLeft(19) + H2) * 5) + 0x561ccd1b; H2 ^= (k2 * C2).RotateLeft(16) * C3; H2 = ((H2.RotateLeft(17) + H3) * 5) + 0x0bcaa747; H3 ^= (k3 * C3).RotateLeft(17) * C4; H3 = ((H3.RotateLeft(15) + H4) * 5) + 0x96cd1c35; H4 ^= (k4 * C4).RotateLeft(18) * C1; H4 = ((H4.RotateLeft(13) + H1) * 5) + 0x32ac3b17; } } if (remainder > 0) { Tail(source.Slice(4 * blocks)); } }
public override unsafe void TransformBlock(ReadOnlyMemory <byte> memory) { var length = memory.Length; if (length == 0) { return; } base.TransformBlock(memory); int remainder = length & 15; int blocks = length / 16; using var hMemory = memory.Pin(); byte * d = (byte *)hMemory.Pointer; ulong *current = (ulong *)d; while (blocks-- > 0) { // a variant of original algorithm optimized for processor instruction pipelining H1 ^= (*current++ *C1).RotateLeft(31) * C2; H1 = (H1.RotateLeft(27) + H2) * 5 + 0x52dce729; H2 ^= (*current++ *C2).RotateLeft(33) * C1; H2 = (H2.RotateLeft(31) + H1) * 5 + 0x38495ab5; } if (remainder > 0) { byte *tail = d + (length - remainder); // create our keys and initialize to 0 ulong k1 = 0, k2 = 0; // determine how many bytes we have left to work with based on length switch (remainder) { case 15: k2 ^= (ulong)tail[14] << 48; goto case 14; case 14: k2 ^= (ulong)tail[13] << 40; goto case 13; case 13: k2 ^= (ulong)tail[12] << 32; goto case 12; case 12: k2 ^= (ulong)tail[11] << 24; goto case 11; case 11: k2 ^= (ulong)tail[10] << 16; goto case 10; case 10: k2 ^= (ulong)tail[9] << 8; goto case 9; case 9: k2 ^= (ulong)tail[8] << 0; goto case 8; case 8: k1 ^= (ulong)tail[7] << 56; goto case 7; case 7: k1 ^= (ulong)tail[6] << 48; goto case 6; case 6: k1 ^= (ulong)tail[5] << 40; goto case 5; case 5: k1 ^= (ulong)tail[4] << 32; goto case 4; case 4: k1 ^= (ulong)tail[3] << 24; goto case 3; case 3: k1 ^= (ulong)tail[2] << 16; goto case 2; case 2: k1 ^= (ulong)tail[1] << 8; goto case 1; case 1: k1 ^= (ulong)tail[0] << 0; break; } H2 ^= (k2 * C2).RotateLeft(33) * C1; H1 ^= (k1 * C1).RotateLeft(31) * C2; } }
public override unsafe void TransformBlock(ReadOnlyMemory <byte> memory) { var length = memory.Length; if (length == 0) { return; } base.TransformBlock(memory); int remainder = length & 15; int blocks = length / 16; using var hMemory = memory.Pin(); byte *d = (byte *)hMemory.Pointer; uint *current = (uint *)d; while (blocks-- > 0) { // K1 - consume first integer H1 ^= (*current++ *C1).RotateLeft(15) * C2; H1 = (H1.RotateLeft(19) + H2) * 5 + 0x561ccd1b; // K2 - consume second integer H2 ^= (*current++ *C2).RotateLeft(16) * C3; H2 = (H2.RotateLeft(17) + H3) * 5 + 0x0bcaa747; // K3 - consume third integer H3 ^= (*current++ *C3).RotateLeft(17) * C4; H3 = (H3.RotateLeft(15) + H4) * 5 + 0x96cd1c35; // K4 - consume fourth integer H4 ^= (*current++ *C4).RotateLeft(18) * C1; H4 = (H4.RotateLeft(13) + H1) * 5 + 0x32ac3b17; } if (remainder > 0) { // create our keys and initialize to 0 uint k1 = 0, k2 = 0, k3 = 0, k4 = 0; byte *tail = d + (length - remainder); // determine how many bytes we have left to work with based on length switch (remainder) { case 15: k4 ^= (uint)tail[14] << 16; goto case 14; case 14: k4 ^= (uint)tail[13] << 8; goto case 13; case 13: k4 ^= (uint)tail[12] << 0; goto case 12; case 12: k3 ^= (uint)tail[11] << 24; goto case 11; case 11: k3 ^= (uint)tail[10] << 16; goto case 10; case 10: k3 ^= (uint)tail[9] << 8; goto case 9; case 9: k3 ^= (uint)tail[8] << 0; goto case 8; case 8: k2 ^= (uint)tail[7] << 24; goto case 7; case 7: k2 ^= (uint)tail[6] << 16; goto case 6; case 6: k2 ^= (uint)tail[5] << 8; goto case 5; case 5: k2 ^= (uint)tail[4] << 0; goto case 4; case 4: k1 ^= (uint)tail[3] << 24; goto case 3; case 3: k1 ^= (uint)tail[2] << 16; goto case 2; case 2: k1 ^= (uint)tail[1] << 8; goto case 1; case 1: k1 ^= (uint)tail[0] << 0; break; } H4 ^= (k4 * C4).RotateLeft(18) * C1; H3 ^= (k3 * C3).RotateLeft(17) * C4; H2 ^= (k2 * C2).RotateLeft(16) * C3; H1 ^= (k1 * C1).RotateLeft(15) * C2; } }