zoukankan      html  css  js  c++  java
  • C# CRC16 CCITT XModem

    核心方法,如果要返回两个字节,则把最后改为 return BitConverter.GetBytes(crc)

            private ushort Crc16Ccitt(byte[] bytes)
             {
                ushort poly = 0x1021;
                ushort[] table = new ushort[256];
                ushort initialValue = 0x0;
                ushort temp, a;
                ushort crc = initialValue;
                for (int i = 0; i < table.Length; ++i)
                {
                    temp = 0;
                    a = (ushort)(i << 8);
                    for (int j = 0; j < 8; ++j)
                    {
                        if (((temp ^ a) & 0x8000) != 0)
                            temp = (ushort)((temp << 1) ^ poly);
                        else
                            temp <<= 1;
                        a <<= 1;
                    }
                    table[i] = temp;
                }
                for (int i = 0; i < bytes.Length; ++i)
                {
                    crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
                }
                return crc;
            }

    提取为类,把查询表提前初始化,避免每次调用都进行计算。

        /// <summary>
        /// CRC16 CCITT XModem计算校验值
        /// </summary>
        public static class CRC16
        {
            /// <summary>
            /// 多项式
            /// </summary>
            const ushort Polynominal = 0x1021;
    
            /// <summary>
            /// 查询表
            /// </summary>
            static ushort[] table = new ushort[256];
    
            /// <summary>
            /// 静态构造函数,初始化查询表
            /// </summary>
            static CRC16()
            {
                ushort temp, a;
                for (int i = 0; i < table.Length; ++i)
                {
                    temp = 0;
                    a = (ushort)(i << 8);
                    for (int j = 0; j < 8; ++j)
                    {
                        if (((temp ^ a) & 0x8000) != 0)
                            temp = (ushort)((temp << 1) ^ Polynominal);
                        else
                            temp <<= 1;
                        a <<= 1;
                    }
                    table[i] = temp;
                }
            }
    
            /// <summary>
            /// 计算校验值
            /// </summary>
            /// <param name="data"></param>
            /// <returns></returns>
            public static byte[] CheckSum(List<byte> data)
            {
                ushort crc = 0x0;
    
                for (int i = 0; i < data.Count; ++i)
                {
                    crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & data[i]))]);
                }
                return BitConverter.GetBytes(crc);
            }
    
            /// <summary>
            /// 计算部分区域的校验值
            /// </summary>
            /// <param name="data"></param>
            /// <param name="startIndex"></param>
            /// <param name="count"></param>
            /// <returns></returns>
            public static byte[] CheckSumRange(List<byte> data, int startIndex, int count)
            {
                return CheckSum(data.GetRange(startIndex, count));
            }
        }

    参考资料:

    CRC16算法

    维基百科

    在线计算CRC值

  • 相关阅读:
    iuplua test failure
    lua C++ wrapper
    lua
    Redux系列01:从一个简单例子了解action、store、reducer
    Meteor入门介绍
    Express入门介绍vs实例讲解
    React半科普文
    Express模版引擎hbs备忘
    Gulp:插件编写入门
    gulp.src()内部实现探究
  • 原文地址:https://www.cnblogs.com/xyz0835/p/9598079.html
Copyright © 2011-2022 走看看