Example #1
0
        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)
        {
            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));
            }
        }
Example #4
0
        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;
            }
        }