我想为CRC-6/CRC 2000-A创建一个表。我尝试了各种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; 我从上面的代码中得到了这个数组:
$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-6:
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);发布于 2022-11-22 20:38:30
有几个问题。您正在将垃圾转移到表条目的前两位,但却没有使用and来清除它们。更重要的是,您正在使用掩码忽略每个初始表条目(i)的前两位,即第6位和第7位,这就是第5位。
要正确地执行此操作,需要计算正在处理的字节(i)的前六位中的CRC。你掩盖了第7位而不是第5位,你把多项式向上移动两位来匹配它。如果你是用一个字节来做这件事,那么它就会处理那些被移动的垃圾,因为它会从字节的顶部掉下来。
你想:
Mask := 1 shl 7;以及:
Table[i] := Table[i] xor (POLYNOMIAL shl 2);现在,您表中的CRCs实际上是您希望它们在的位置,它位于每个字节的前六位。然后,您不需要对计算的每个字节执行CRC shl 2。相反,计算中的这一行将变成:
CRC := CRC_Table[CRC xor ord(Str[i])];然后,在循环之后,您需要将CRC向下移2以返回低6位中的CRC:
CRC := CRC shr 2;初始值需要向上移动两个:
CRC := $fc;这将给出测试向量的正确答案,即$0D。
我不清楚为什么您的表生成有三个带有数组的循环。用一个循环和没有数组(没有测试--我不知道Pascal/Delphi),这样做似乎更简单:
var
i: Integer;
j: Integer;
crc: Byte;
S: String;
begin
S := '';
for i := 0 to 255 do begin
crc := i;
for j := 0 to 7 do
if ((crc and $80) <> 0) then
crc := (crc shl 1) xor $9c
else
crc := crc shl 1;
S := S + '$' + IntToHex(crc, 2) + ', ';
if i mod 16 = 15 then begin
Memo1.Lines.Add(S);
S := '';
end;
end;
end.https://stackoverflow.com/questions/74535155
复制相似问题