Esempio n. 1
0
        public static unsafe UInt32 CalculateForPacketBuffer(ConanStream packetBuffer)
        {
            fixed(byte *fix = packetBuffer.GetBuffer())
            {
                var    buffer = (UInt32 *)fix + 2; // skip length and hash
                var    len    = packetBuffer.Length - sizeof(UInt32) * 2;
                var    crc32  = 0xffffffff;
                UInt32 offset = 0;

                if (len >= 32)
                {
                    for (UInt32 i = 0; i < len >> 5; i++)
                    {
                        crc32 ^= buffer[offset];
                        len   -= 4;

                        for (UInt32 ii = 0; ii < 7; ii++)
                        {
                            offset++;
                            crc32 = CrcTab2[crc32 >> 16 & 0xFF] ^ CrcTab3[crc32 >> 8 & 0xFF] ^ CrcTab1[crc32 >> 24] ^
                                    CrcTab4[crc32 & 0xFF] ^ buffer[offset];
                            len -= 4;
                        }

                        crc32 = CrcTab2[crc32 >> 16 & 0xFF] ^ CrcTab3[crc32 >> 8 & 0xFF] ^ CrcTab1[crc32 >> 24] ^
                                CrcTab4[crc32 & 0xFF];
                        offset++;
                    }
                }

                if (len >= offset)
                {
                    for (UInt32 i = 0; i < (len >> 2); i++)
                    {
                        crc32 ^= buffer[offset];
                        len   -= 4;

                        crc32 = CrcTab2[crc32 >> 16 & 0xFF] ^ CrcTab3[crc32 >> 8 & 0xFF] ^ CrcTab1[crc32 >> 24] ^
                                CrcTab4[crc32 & 0xFF];
                        offset++;
                    }
                }

                if (len > 0)
                {
                    offset *= 4;

                    for (UInt32 i = 0; i < len; i++)
                    {
                        var tmp = *(byte *)((UInt64)buffer + offset);
                        crc32 = (crc32 >> 8) ^ CrcTab1[(tmp ^ crc32) & 0xFF];
                        offset++;
                    }
                }

                return(crc32 ^ 0xFFFFFFFF);
            }
        }