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); } }