如何检测字节序列中的CRC?验证并破解疑似CRC字节方案
确认最后2字节是否为CRC及破解CRC算法的方法
一、先验证最后2字节是否为CRC
- 找重复数据佐证:你提供的样本里有完全重复的行:
30E4558679009904400030000110846C,前28字节一致,最后2字节也完全相同,这符合CRC的核心特性——相同输入必然对应相同校验值,这是第一个有力证据。 - 对比差异看雪崩效应:把结构相似的行放一起对比,比如前5行(开头
305X、含D9D8、结尾0110),修改部分字节后,最后2字节变化极大,比如第一行305B80DB3D009F04D9D848000110097C和第二行305BA9983E00A304D9D852000110F3A3,仅前几个字节不同,校验值从097C变成F3A3,这种“微小输入变化导致校验值大幅变动”的雪崩效应,也是CRC的典型表现。
二、破解CRC算法的实用步骤
1. 先整理样本数据
把每行拆成主体部分(去掉最后2字节)和校验值(最后2字节),格式如下:
- 样本1:主体
305B80DB3D009F04D9D848000110,校验097C - 样本2:主体
305BA9983E00A304D9D852000110,校验F3A3 - 剩下的样本都按这个规则拆分好,方便后续测试。
2. 调整CRC-RevEng的参数重试
你之前用RevEng没成功,大概率是没覆盖全参数组合,试试这些方向:
- 指定校验位长度:
reveng -w 16(因为是2字节,对应16位CRC) - 枚举常见初始值:
0x0000、0xFFFF、0x1D0F这些都是标准CRC常用的初始值 - 试遍标准16位多项式:
0x8005(CRC-16-IBM/Modbus)、0x1021(CRC-16-CCITT)、0x08005(CRC-16-DNP)等 - 调整字节序和反转:加
--little/--big指定字节序,加--refin/--refout开启输入/输出字节反转(很多工业CRC会用反转)
3. 用Python脚本暴力枚举参数
如果RevEng还是没结果,写个简单脚本枚举常见参数组合,匹配你的样本:
import crcmod # 整理常见的16位CRC参数组合 crc_param_list = [ (0x8005, 0x0000, False, False), (0x8005, 0xFFFF, True, True), (0x1021, 0x0000, False, False), (0x1021, 0xFFFF, True, True), (0x8005, 0xFFFF, False, False), (0x1021, 0x1D0F, False, False), ] # 替换成你整理好的样本数据 test_samples = [ ("305B80DB3D009F04D9D848000110", "097C"), ("305BA9983E00A304D9D852000110", "F3A3"), ("305CA40340009F04D9D83C000110", "8730"), # 把所有样本都加进来 ] # 遍历参数匹配 for poly, init_val, refin_flag, refout_flag in crc_param_list: crc_calc = crcmod.mkCrcFun(poly, initCrc=init_val, rev=refin_flag, xorOut=0x0000) all_match = True for data_hex, crc_target in test_samples: data_bytes = bytes.fromhex(data_hex) result = crc_calc(data_bytes) # 处理输出反转 if refout_flag: result = int(f"{result:016b}"[::-1], 2) if f"{result:04X}".upper() != crc_target.upper(): all_match = False break if all_match: print(f"找到匹配的CRC参数:") print(f"多项式: 0x{poly:04X}, 初始值: 0x{init_val:04X}") print(f"输入反转: {refin_flag}, 输出反转: {refout_flag}") break else: print("常见参数没匹配到,可能是自定义多项式,或者数据有额外处理")
4. 排查是否有额外处理
如果上述方法都失败,要考虑这些可能性:
- 校验值字节序反转:比如最后2字节是
097C,实际校验值是7C09,可以把所有校验值反转后再试 - 主体数据有隐藏前缀/后缀:比如计算CRC时,会在主体前后加固定字节(比如开头加
0x30或结尾加0x00) - 不是CRC而是其他校验:比如简单校验和(把主体所有字节相加取低2字节)、XOR校验,先试试校验和是否匹配。
内容的提问来源于stack exchange,提问作者user737329
相关产品推荐
相关产品推荐

