You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CRC16查表法校验异常:追加校验值后计算结果非0

CRC16查表法校验结果不为0的问题排查

问题描述

已实现基于查表法的CRC16算法(多项式0xA001),执行以下操作后预期校验值为0,但实际结果不符:

  • 创建测试数组data[6] = {0x10,0x20,0x30,0x40,0,0},取前4字节以初始值0xFFFF计算CRC,存入变量crc
  • 将crc追加到数组末尾,再用整个数组计算新的校验值crc_2,预期crc_2为0

代码中的错误点

1. CRC值拷贝错误

代码中误用memcpy((void*)&data[4], (void*)&crc_2, 2);,但crc_2初始值为0,实际应该拷贝的是计算得到的crc变量,正确写法:

memcpy((void*)&data[4], (void*)&crc, 2);

2. 第二次CRC计算的初始值错误

第二次计算时,应使用和第一次相同的初始值0xFFFF,而非传入之前得到的crc。CRC校验的标准逻辑是:原始数据+CRC校验码,用标准初始值计算,结果应为0。因此第二次调用应改为:

crc_2 = fast_crc16(0XFFFF, data, 6);

修正后的完整代码

#include <stdio.h>
#include <string.h>
#include <stdint.h>

uint16_t crc16_tab[256] =
{
    0x0000, 0xA001, 0xE003, 0x4002, 0x6007, 0xC006, 0x8004, 0x2005, 0xC00E, 0x600F, 0x200D, 0x800C, 0xA009, 0x0008, 0x400A, 0xE00B,
    0x201D, 0x801C, 0xC01E, 0x601F, 0x401A, 0xE01B, 0xA019, 0x0018, 0xE013, 0x4012, 0x0010, 0xA011, 0x8014, 0x2015, 0x6017, 0xC016,
    0x403A, 0xE03B, 0xA039, 0x0038, 0x203D, 0x803C, 0xC03E, 0x603F, 0x8034, 0x2035, 0x6037, 0xC036, 0xE033, 0x4032, 0x0030, 0xA031,
    0x6027, 0xC026, 0x8024, 0x2025, 0x0020, 0xA021, 0xE023, 0x4022, 0xA029, 0x0028, 0x402A, 0xE02B, 0xC02E, 0x602F, 0x202D, 0x802C,
    0x8074, 0x2075, 0x6077, 0xC076, 0xE073, 0x4072, 0x0070, 0xA071, 0x407A, 0xE07B, 0xA079, 0x0078, 0x207D, 0x807C, 0xC07E, 0x607F,
    0xA069, 0x0068, 0x406A, 0xE06B, 0xC06E, 0x606F, 0x206D, 0x806C, 0x6067, 0xC066, 0x8064, 0x2065, 0x0060, 0xA061, 0xE063, 0x4062,
    0xC04E, 0x604F, 0x204D, 0x804C, 0xA049, 0x0048, 0x404A, 0xE04B, 0x0040, 0xA041, 0xE043, 0x4042, 0x6047, 0xC046, 0x8044, 0x2045,
    0xE053, 0x4052, 0x0050, 0xA051, 0x8054, 0x2055, 0x6057, 0xC056, 0x205D, 0x805C, 0xC05E, 0x605F, 0x405A, 0xE05B, 0xA059, 0x0058,
    0xA0E9, 0x00E8, 0x40EA, 0xE0EB, 0xC0EE, 0x60EF, 0x20ED, 0x80EC, 0x60E7, 0xC0E6, 0x80E4, 0x20E5, 0x00E0, 0xA0E1, 0xE0E3, 0x40E2,
    0x80F4, 0x20F5, 0x60F7, 0xC0F6, 0xE0F3, 0x40F2, 0x00F0, 0xA0F1, 0x40FA, 0xE0FB, 0xA0F9, 0x00F8, 0x20FD, 0x80FC, 0xC0FE, 0x60FF,
    0xE0D3, 0x40D2, 0x00D0, 0xA0D1, 0x80D4, 0x20D5, 0x60D7, 0xC0D6, 0x20DD, 0x80DC, 0xC0DE, 0x60DF, 0x40DA, 0xE0DB, 0xA0D9, 0x00D8,
    0xC0CE, 0x60CF, 0x20CD, 0x80CC, 0xA0C9, 0x00C8, 0x40CA, 0xE0CB, 0x00C0, 0xA0C1, 0xE0C3, 0x40C2, 0x60C7, 0xC0C6, 0x80C4, 0x20C5,
    0x209D, 0x809C, 0xC09E, 0x609F, 0x409A, 0xE09B, 0xA099, 0x0098, 0xE093, 0x4092, 0x0090, 0xA091, 0x8094, 0x2095, 0x6097, 0xC096,
    0x0080, 0xA081, 0xE083, 0x4082, 0x6087, 0xC086, 0x8084, 0x2085, 0xC08E, 0x608F, 0x208D, 0x808C, 0xA089, 0x0088, 0x408A, 0xE08B,
    0x60A7, 0xC0A6, 0x80A4, 0x20A5, 0x00A0, 0xA0A1, 0xE0A3, 0x40A2, 0xA0A9, 0x00A8, 0x40AA, 0xE0AB, 0xC0AE, 0x60AF, 0x20AD, 0x80AC,
    0x40BA, 0xE0BB, 0xA0B9, 0x00B8, 0x20BD, 0x80BC, 0xC0BE, 0x60BF, 0x80B4, 0x20B5, 0x60B7, 0xC0B6, 0xE0B3, 0x40B2, 0x00B0, 0xA0B1
};

uint16_t fast_crc16(uint16_t crc,uint8_t* buffer, uint32_t len) 
{
    while (len--)
    {
        crc = crc16_tab[(crc >> 8) ^ *buffer++] ^ (crc << 8);
    }

    return (crc);
}

int main() {

    /*DUMMY MESSAGE*/
    uint8_t data[6] = {0x10,0x20, 0X30,0X40,0,0};
    uint16_t crc = 0;
    uint16_t crc_2 = 0;

    /*FIRST CRC*/
    crc = fast_crc16(0XFFFF,data, 4);

    /*COPY CRC INTO DATA - 修正:拷贝crc变量而非crc_2*/
    memcpy((void*)&data[4], (void*)&crc, 2);

    /*SECOND CRC - 修正:使用初始值0xFFFF而非crc*/
    crc_2 = fast_crc16(0XFFFF,data, 6);

    printf("%x\n", crc_2); // 此时输出应为0
    return 0;
}

验证说明

修正后,第一次计算前4字节得到的CRC会被正确追加到数组末尾,第二次用初始值0xFFFF计算整个6字节数据,结果将为0,符合CRC校验的预期逻辑。


内容的提问来源于stack exchange,提问作者Filippo_Col

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:37:07