delphi 如何生成CRC-6的CRC表?

svgewumm  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(187)

我想为CRC-6/CDMA2000-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);
e0uiprwp

e0uiprwp1#

这里有几个问题。你把垃圾移到了表项的前两位,但是没有用and把它们去掉。更重要的是,你忽略了每个初始表项(i)的前两位,第6位和第7位,而你的掩码是第5位。
为了正确地执行此操作,需要计算正在处理的字节(i)的前6位的CRC。您屏蔽了位7而不是位5,并将多项式上移2位以匹配它。如果您在一个字节中执行此操作,则会处理上移的垃圾,因为它会从字节的顶部脱落。
您需要:

Mask := 1 shl 7;

以及:

Table[i] := Table[i] xor (POLYNOMIAL shl 2);

现在,表中的CRC实际上就在你想要的位置,也就是每个字节的前6位,这样你就不需要对每一个字节都进行CRC shl 2运算了,而是在你的计算中变成了:

CRC := CRC_Table[CRC xor ord(Str[i])];

然后,在循环之后,您需要将CRC下移2位,以返回低6位的CRC:

CRC := CRC shr 2;

并且初始值需要上移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.

相关问题