csharp/499116344/qqProtocol/QQ.Framework/Utils/CRC32.cs

CRC32.cs
using System;
using System.Text;

namespace QQ.Framework.Utils
{
    public clast CRC32
    {
        private static ushort[] _crc16Table;

        private static uint[] _crc32Table;

        protected static ulong[] _crc32Table2;

        private static void MakeCRC16Table()
        {
            if (_crc16Table != null)
            {
                return;
            }

            _crc16Table = new ushort[256];
            for (ushort num = 0; num < 256; num += 1)
            {
                var num2 = num;
                for (var i = 0; i < 8; i++)
                {
                    if (num2 % 2 == 0)
                    {
                        num2 = (ushort) (num2 >> 1);
                    }
                    else
                    {
                        num2 = (ushort) ((num2 >> 1) ^ 33800);
                    }
                }

                _crc16Table[num] = num2;
            }
        }

        private static void MakeCRC32Table()
        {
            if (_crc32Table != null)
            {
                return;
            }

            _crc32Table = new uint[256];
            for (var num = 0u; num < 256u; num += 1u)
            {
                var num2 = num;
                for (var i = 0; i < 8; i++)
                {
                    if (num2 % 2u == 0u)
                    {
                        num2 >>= 1;
                    }
                    else
                    {
                        num2 = (num2 >> 1) ^ 3988292384u;
                    }
                }

                _crc32Table[(int) (UIntPtr) num] = num2;
            }
        }

        private static ushort UpdateCRC16(byte aByte, ushort aSeed)
        {
            return (ushort) (_crc16Table[(aSeed & 255) ^ aByte] ^ (aSeed >> 8));
        }

        private static uint UpdateCRC32(byte aByte, uint aSeed)
        {
            return _crc32Table[(int) (UIntPtr) ((aSeed & 255u) ^ aByte)] ^ (aSeed >> 8);
        }

        private static ushort CRC16(byte[] aBytes)
        {
            MakeCRC16Table();
            ushort num = 65535;
            foreach (var aByte in aBytes)
            {
                num = UpdateCRC16(aByte, num);
            }

            return num;
        }

        private static ushort CRC16(string aString, Encoding aEncoding)
        {
            return CRC16(aEncoding.GetBytes(aString));
        }

        private static ushort CRC16(string aString)
        {
            return CRC16(aString, Encoding.UTF8);
        }

        public static uint CRC32Imp(byte[] aBytes)
        {
            MakeCRC32Table();
            var num = 4294967295u;
            foreach (var aByte in aBytes)
            {
                num = UpdateCRC32(aByte, num);
            }

            return CRC32ToUint(~num);
        }

        public static uint CRC32Reverse(byte[] aBytes)
        {
            MakeCRC32Table();
            var num = 4294967295u;
            foreach (var aByte in aBytes)
            {
                num = UpdateCRC32(aByte, num);
            }

            return CRC32ToUintReverse(~num);
        }

        //生成CRC32码表
        public static void GetCRC32Table()
        {
            _crc32Table2 = new ulong[256];
            int i;
            for (i = 0; i < 256; i++)
            {
                var crc = (ulong) i;
                int j;
                for (j = 8; j > 0; j--)
                {
                    if ((crc & 1) == 1)
                    {
                        crc = (crc >> 1) ^ 0xEDB88320;
                    }
                    else
                    {
                        crc >>= 1;
                    }
                }

                _crc32Table2[i] = crc;
            }
        }

        //获取字符串的CRC32校验值
        public static ulong GetCRC32Str(string sInputString)
        {
            //生成码表
            GetCRC32Table();
            var buffer = Encoding.ASCII.GetBytes(sInputString);
            ulong value = 0xffffffff;
            var len = buffer.Length;
            for (var i = 0; i < len; i++)
            {
                value = (value >> 8) ^ _crc32Table2[(value & 0xFF) ^ buffer[i]];
            }

            return value ^ 0xffffffff;
        }

        public static ulong GetCRC32(byte[] buffer)
        {
            //生成码表
            GetCRC32Table();
            ulong value = 0xffffffff;
            var len = buffer.Length;
            for (var i = 0; i < len; i++)
            {
                value = (value >> 8) ^ _crc32Table2[(value & 0xFF) ^ buffer[i]];
            }

            return value ^ 0xffffffff;
        }

        private static uint CRC32Imp(string aString, Encoding aEncoding)
        {
            return CRC32Imp(aEncoding.GetBytes(aString));
        }

        private static uint CRC32Imp(string aString)
        {
            return CRC32Imp(aString, Encoding.UTF8);
        }

        private static uint CRC32ToUint(uint crc32)
        {
            var text = crc32.ToString("X2");
            if (text.Length == 7)
            {
                text = "0" + text;
            }

            var text2 = "";
            for (var i = 6; i >= 0; i -= 2)
            {
                text2 = text2 + text.Substring(i, 2) + " ";
            }

            uint result;
            try
            {
                result = Convert.ToUInt32(text2.Replace(" ", ""), 16);
            }
            catch
            {
                result = 0u;
            }

            return result;
        }

        private static uint CRC32ToUintReverse(uint crc32)
        {
            var text = crc32.ToString("X2");
            var text2 = "";
            for (var i = 6; i >= 0; i -= 2)
            {
                text2 = text.Substring(i, 2) + " " + text2;
            }

            uint result;
            try
            {
                result = Convert.ToUInt32(text2.Replace(" ", ""), 16);
            }
            catch
            {
                result = 0u;
            }

            return result;
        }
    }
}