crc16求未知多项式ploy和crc初始值init

本文介绍了如何通过编程解决在老旧电气设备通信中遇到的CRC16校验问题,对比了直接计算法和全字节查表法的效率,并提供了C#代码示例。

背景:

破解老旧电气设备通讯,使用串口助手截获数据(Hex)并分析,假定各字节作用——校验码两字节16位,尝试常见 crc16 计算校验码均失败。

目标:

根据已有数据,通过编程计算出未知多项式 ploy 和crc初始值 init 。

编程思路:

crc16 的 ploy 和 init 均为16位(0~0xFFFF),两层for循环尝试所有 poly 和 init 的组合可能(65536*65536),使poly和init能代入已有数据。

编程环境:

计算机:联想拯救者Y7000 2019 PG0 (CPU:英特尔 Core i5-9300H @ 2.40GHz 四核,内存:8 GB ,记忆科技 DDR4 2666MHz )
IDE:Visual Studio 2019
编程语言:C#
其它:.Net 5.0 + Windows 应用程序

代码效果(尝试所有 poly 和 init 的组合可能所花费的时间):

1.采用 crc 直接计算法,60+分钟。
2.采用 crc 全字节查表法,< 4分钟。

代码( crc 直接计算法):

#region crc16求未知多项式ploy和crc初始值init
    /// <summary>
    /// crc16求未知多项式ploy和crc初始值init
    /// </summary>
    public class CRC16_Get_Polynomial_InitialValue
    {
   
   
        static CRC16_Get_Polynomial_InitialValue()
        {
   
   

        }

        /// <summary>
        /// crc16求未知多项式ploy和crc初始值init
        /// </summary>
        /// <returns></returns>
        public  ushort CRC16_get_Polynomial_InitialValue()
        {
   
   
            //已知参与计算校验码的数据(除帧头、固定字段、校验位、帧尾以外的数据)
            byte[] date1 = {
   
    0x01, 0x04, 0x0C, 0x01, 0x00, 0x32, 0x00 };
            byte[] date2 = {
   
    0x01, 0x04, 0x0C, 0x01, 0x00, 0x31, 0x00 };
            byte[] date3 = {
   
    0x01, 0x04, 0x0A, 0x01, 0x00, 0x0C, 0x00 };
            //已知数据的校验码
            ushort crc1 = 0x59D8;
            ushort crc2 = 0x31F2;
            ushort crc3 = 0x73CF;
            //假设计算得到校验码后交换高低字节数据,还原校验码未交换高低字节前的数据
            ushort crc11 = (ushort)(crc1 << 8 | crc1 >> 8);
            ushort crc22 = (ushort)(crc2 << 8 | crc2 >> 8);
            ushort crc33 = (ushort)(crc3 << 8 | crc3 >> 8);

            
            bool get = false;//用于得到poly和init后终止for循环
            //poly为多项式, 使用for循环来尝试不同的poly值
            for (int poly = 0; poly <= 0xFFFF; poly++)
            {
   
   
                //校验得出的poly是否唯一
                //if (poly == 0x8408)
                //{
   
   
                //    continue;
                //}
                //init为crc初始值,使用for循环来尝试不同的init值 
                for (int init = 0; init <= 0xFFFF; init++)
                {
   
   
                    ushort cRc_16 = 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值