CRC-6 GSM查表计算结果错误,求Pascal代码修正方案
CRC-6 GSM查表法实现错误排查与修正
我尝试用查表法计算CRC-6 GSM,计算字符串'123456789'时得到结果$16,但正确结果应为$13。
以下是我的Pascal实现代码:
var Table: array[0..255] of Byte = ( $3F, $10, $0E, $21, $32, $1D, $03, $2C, $25, $0A, $14, $3B, $28, $07, $19, $36, $0B, $24, $3A, $15, $06, $29, $37, $18, $11, $3E, $20, $0F, $1C, $33, $2D, $02, $38, $17, $09, $26, $35, $1A, $04, $2B, $22, $0D, $13, $3C, $2F, $00, $1E, $31, $0C, $23, $3D, $12, $01, $2E, $30, $1F, $16, $39, $27, $08, $1B, $34, $2A, $05, $31, $1E, $00, $2F, $3C, $13, $0D, $22, $2B, $04, $1A, $35, $26, $09, $17, $38, $05, $2A, $34, $1B, $08, $27, $39, $16, $1F, $30, $2E, $01, $12, $3D, $23, $0C, $36, $19, $07, $28, $3B, $14, $0A, $25, $2C, $03, $1D, $32, $21, $0E, $10, $3F, $02, $2D, $33, $1C, $0F, $20, $3E, $11, $18, $37, $29, $06, $15, $3A, $24, $0B, $23, $0C, $12, $3D, $2E, $01, $1F, $30, $39, $16, $08, $27, $34, $1B, $05, $2A, $17, $38, $26, $09, $1A, $35, $2B, $04, $0D, $22, $3C, $13, $00, $2F, $31, $1E, $24, $0B, $15, $3A, $29, $06, $18, $37, $3E, $11, $0F, $20, $33, $1C, $02, $2D, $10, $3F, $21, $0E, $1D, $32, $2C, $03, $0A, $25, $3B, $14, $07, $28, $36, $19, $2D, $02, $1C, $33, $20, $0F, $11, $3E, $37, $18, $06, $29, $3A, $15, $0B, $24, $19, $36, $28, $07, $14, $3B, $25, $0A, $03, $2C, $32, $1D, $0E, $21, $3F, $10, $2A, $05, $1B, $34, $27, $08, $16, $39, $30, $1F, $01, $2E, $3D, $12, $0C, $23, $1E, $31, $2F, $00, $13, $3C, $22, $0D, $04, $2B, $35, $1A, $09, $26, $38, $17 ); function GSM_Update(Msg: PByte; Length: Integer): Byte; var i: Integer; H: Byte; begin H := $00; for i:=0 to Length-1 do begin H := Table[H xor Msg^]; // 我怀疑这一行有问题,但不知道怎么改 Inc(Msg); end; Result := H xor $3F; end;
调用方式:
var Msg: AnsiString; ... GSM_Update(@Msg[1], Length(Msg));
或者
var Msg: array of AnsiChar; Len: Integer; ... SetLength(Msg, Len); GSM_Update(@Msg[0], Len);
问题分析与修正
CRC-6 GSM的核心算法规则是:初始CRC值为$3F,输入字节取高6位参与运算,最终结果无需额外异或。你的代码存在三个关键错误:
- 初始值错误:代码中
H初始化为$00,但标准CRC-6 GSM要求初始值为$3F。 - 字节处理逻辑错误:直接用完整字节和CRC值异或,忽略了CRC-6仅使用6位的特性,需将输入字节右移2位(取高6位)后再与CRC值异或。
- 冗余的最终异或:结尾的
H xor $3F是多余操作,标准算法不需要这一步。
修正后的函数代码:
function GSM_Update(Msg: PByte; Length: Integer): Byte; var i: Integer; H: Byte; begin H := $3F; // 修正初始值 for i := 0 to Length-1 do begin // 取输入字节高6位,与当前CRC值异或后查表 H := Table[(H xor (Msg^ shr 2)) and $3F]; Inc(Msg); end; Result := H; // 移除多余异或 end;
如果你的CRC表是正确的,使用修正后的代码计算'123456789'将得到正确结果$13。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

