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

如何生成CRC-6/CDMA2000-A的CRC表?现有代码生成结果异常

CRC-6/CDMA2000-A 查表生成与计算故障排查

问题说明

我需要创建CRC-6/CDMA2000-A的CRC查表,此前用下述算法生成各类CRC-8的表均正常,但生成CRC-6的表后,无论是表本身还是使用该表计算CRC-6的函数都无法正常工作。

原查表生成代码

const POLYNOMIAL = $27;
      BitsCRC = 6;
var Table: array[0..255] of Byte;
    i: Integer;
    j: Integer;
    temp: Byte;
    S: String;
    Mask: Byte;
begin
  mask := (1 shl (BitsCRC - 1));

  for i:=0 to 255 do Table[i] := i ;

  for i:=0 to 255 do begin
        for j:=7 downto 0 do begin
            temp := Table[i] and Mask;

            if (temp <> 0) then begin
                Table[i] := Table[i] shl 1;
                Table[i] := Table[i] xor POLYNOMIAL;
            end
            else begin
                Table[i] := Table[i] shl 1;
            end;
        end;
    end;


  S := '';
  for i:=0 to 255 do begin
    S := S + '$' + IntToHex(Table[i], 2) +', ';
    if i mod 16 = 15 then begin
      Memo1.Lines.Add(s);
      S := '';
    end;
  end;   
end;

生成的错误数组

$00, $F5, $CD, $38, $9A, $6F, $57, $A2, $34, $C1, $F9, $0C, $AE, $5B, $63, $96,
$4F, $BA, $82, $77, $D5, $20, $18, $ED, $7B, $8E, $B6, $43, $E1, $14, $2C, $D9,
$9E, $6B, $53, $A6, $04, $F1, $C9, $3C, $AA, $5F, $67, $92, $30, $C5, $FD, $08,
$D1, $24, $1C, $E9, $4B, $BE, $86, $73, $E5, $10, $28, $DD, $7F, $8A, $B2, $47,
$00, $F5, $CD, $38, $9A, $6F, $57, $A2, $34, $C1, $F9, $0C, $AE, $5B, $63, $96,
$4F, $BA, $82, $77, $D5, $20, $18, $ED, $7B, $8E, $B6, $43, $E1, $14, $2C, $D9,
$9E, $6B, $53, $A6, $04, $F1, $C9, $3C, $AA, $5F, $67, $92, $30, $C5, $FD, $08,
$D1, $24, $1C, $E9, $4B, $BE, $86, $73, $E5, $10, $28, $DD, $7F, $8A, $B2, $47,
$00, $F5, $CD, $38, $9A, $6F, $57, $A2, $34, $C1, $F9, $0C, $AE, $5B, $63, $96,
$4F, $BA, $82, $77, $D5, $20, $18, $ED, $7B, $8E, $B6, $43, $E1, $14, $2C, $D9,
$9E, $6B, $53, $A6, $04, $F1, $C9, $3C, $AA, $5F, $67, $92, $30, $C5, $FD, $08,
$D1, $24, $1C, $E9, $4B, $BE, $86, $73, $E5, $10, $28, $DD, $7F, $8A, $B2, $47,
$00, $F5, $CD, $38, $9A, $6F, $57, $A2, $34, $C1, $F9, $0C, $AE, $5B, $63, $96,
$4F, $BA, $82, $77, $D5, $20, $18, $ED, $7B, $8E, $B6, $43, $E1, $14, $2C, $D9,
$9E, $6B, $53, $A6, $04, $F1, $C9, $3C, $AA, $5F, $67, $92, $30, $C5, $FD, $08,
$D1, $24, $1C, $E9, $4B, $BE, $86, $73, $E5, $10, $28, $DD, $7F, $8A, $B2, $47

原CRC计算代码

procedure crc6_update(var CRC: Byte; Str: String);
var i: Integer;
begin
  for i:=1 to Length(Str) do    
       CRC := CRC_Table[(CRC shl 2) xor ord(Str[i]) ] ;
 
end;           

CRC := $3f;
crc6_update(CRC, '123456789');

Caption := IntToHex(CRC, 2);

问题分析与修正方案

核心问题

  1. 查表生成逻辑错误:原代码初始将Table[i]设为i,直接在原数组上循环移位修改,未限制CRC-6的6位宽度,导致移位后高两位数据干扰计算,最终表项出现重复(每64个值循环一次)。
  2. 计算代码未截断位宽:CRC是6位值,计算时未确保始终只保留低6位,可能引入无效的高两位数据。

修正后的查表生成代码

const POLYNOMIAL = $27;
      BitsCRC = 6;
var Table: array[0..255] of Byte;
    i: Integer;
    j: Integer;
    temp: Byte;
    S: String;
    CRC_MASK: Byte; // 用于截断到6位
begin
  CRC_MASK := (1 shl BitsCRC) - 1; // 0x3F

  for i := 0 to 255 do begin
    temp := i; // 以当前字节为初始值
    for j := 7 downto 0 do begin
      // 检查当前字节的最高位
      if (temp and $80) <> 0 then begin
        temp := (temp shl 1) xor POLYNOMIAL;
      end else begin
        temp := temp shl 1;
      end;
    end;
    Table[i] := temp and CRC_MASK; // 只保留低6位结果
  end;

  // 输出表的代码不变
  S := '';
  for i:=0 to 255 do begin
    S := S + '$' + IntToHex(Table[i], 2) +', ';
    if i mod 16 = 15 then begin
      Memo1.Lines.Add(s);
      S := '';
    end;
  end;   
end;

修正后的CRC计算代码

procedure crc6_update(var CRC: Byte; Str: String);
var i: Integer;
    index: Byte;
begin
  CRC := CRC and $3F; // 确保初始值是6位有效数据
  for i := 1 to Length(Str) do begin
    // CRC左移2位补0,与输入字节异或得到查表索引
    index := (CRC shl 2) xor ord(Str[i]);
    // 查表后保留低6位
    CRC := CRC_Table[index] and $3F;
  end;
end;           

// 测试代码
var CRC: Byte;
begin
  CRC := $3F; // CRC-6/CDMA2000-A标准初始值
  crc6_update(CRC, '123456789');
  // 标准结果应为0x00
  Caption := IntToHex(CRC, 2);
end;

验证说明

CRC-6/CDMA2000-A的标准参数为:

  • 多项式:0x27(二进制100111)
  • 初始值:0x3F
  • 输入反转:无
  • 输出反转:无
  • 输出异或:0x00

使用修正后的代码计算字符串123456789,结果应为0x00,符合标准校验值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:10:40