Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Delphi: Общие вопросы > Помогите с написанием функции по вычислению CRC16 и распознать алгоритм.


Автор: User32 27.03.12, 09:22
Приветствую всех.

Проблема заключается в подсчёте CRC16 из буфера.
Контрольная сумма представлена 2 байтами и в эталоне это: 9B D7
В буфере 11 байт из чего она вычисляется: 73 48 00 0D 00 00 00 00 00 00 00

_876576764343.GIF (, : 1344)

Пример во вложении TEST1.zip (, : 437) .

Но у меня почемуто не выходит эталонная сумма :unsure:

Автор: Pavia 27.03.12, 15:51
Цитата
2. The CRC is calculated using the standard polynomial 0xEDB88320. In
case the size of the CRC is less than 4 bytes, only the low order bytes
are used.

Автор: User32 28.03.12, 13:26
Цитата Pavia @
Цитата
2. The CRC is calculated using the standard polynomial 0xEDB88320. In
case the size of the CRC is less than 4 bytes, only the low order bytes
are used.

И что:
2. CRC вычисляется с помощью стандартного 0xEDB88320 многочлена.
В случае, если размер CRC меньше 4 байт, используются только младшие байты.

Уже пробовал, та же петрушка :(

Сейчас нашёл в ВИКИ такой вот пример:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    /*
      Name  : CRC-16 CCITT
      Poly  : 0x1021    x^16 + x^12 + x^5 + 1
      Init  : 0xFFFF
      Revert: false
      XorOut: 0x0000
      Check : 0x29B1 ("123456789")
      MaxLen: 4095 байт (32767 бит) - обнаружение
        одинарных, двойных, тройных и всех нечетных ошибок
    */
    const unsigned short Crc16Table[256] = {
        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
    };
     
    unsigned short Crc16(unsigned char * pcBlock, unsigned short len)
    {
        unsigned short crc = 0xFFFF;
     
        while (len--)
            crc = (crc << 8) ^ Crc16Table[(crc >> 8) ^ *pcBlock++];
     
        return crc;
    }


Помогите перевести на Delphi:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    function Crc16(pcBlock: array of byte; len: Word): Word;
    const Crc16Table: array[0..255] of WORD = (
        $0000, $1021, $2042, $3063, $4084, $50A5, $60C6, $70E7,
        $8108, $9129, $A14A, $B16B, $C18C, $D1AD, $E1CE, $F1EF,
        $1231, $0210, $3273, $2252, $52B5, $4294, $72F7, $62D6,
        $9339, $8318, $B37B, $A35A, $D3BD, $C39C, $F3FF, $E3DE,
        $2462, $3443, $0420, $1401, $64E6, $74C7, $44A4, $5485,
        $A56A, $B54B, $8528, $9509, $E5EE, $F5CF, $C5AC, $D58D,
        $3653, $2672, $1611, $0630, $76D7, $66F6, $5695, $46B4,
        $B75B, $A77A, $9719, $8738, $F7DF, $E7FE, $D79D, $C7BC,
        $48C4, $58E5, $6886, $78A7, $0840, $1861, $2802, $3823,
        $C9CC, $D9ED, $E98E, $F9AF, $8948, $9969, $A90A, $B92B,
        $5AF5, $4AD4, $7AB7, $6A96, $1A71, $0A50, $3A33, $2A12,
        $DBFD, $CBDC, $FBBF, $EB9E, $9B79, $8B58, $BB3B, $AB1A,
        $6CA6, $7C87, $4CE4, $5CC5, $2C22, $3C03, $0C60, $1C41,
        $EDAE, $FD8F, $CDEC, $DDCD, $AD2A, $BD0B, $8D68, $9D49,
        $7E97, $6EB6, $5ED5, $4EF4, $3E13, $2E32, $1E51, $0E70,
        $FF9F, $EFBE, $DFDD, $CFFC, $BF1B, $AF3A, $9F59, $8F78,
        $9188, $81A9, $B1CA, $A1EB, $D10C, $C12D, $F14E, $E16F,
        $1080, $00A1, $30C2, $20E3, $5004, $4025, $7046, $6067,
        $83B9, $9398, $A3FB, $B3DA, $C33D, $D31C, $E37F, $F35E,
        $02B1, $1290, $22F3, $32D2, $4235, $5214, $6277, $7256,
        $B5EA, $A5CB, $95A8, $8589, $F56E, $E54F, $D52C, $C50D,
        $34E2, $24C3, $14A0, $0481, $7466, $6447, $5424, $4405,
        $A7DB, $B7FA, $8799, $97B8, $E75F, $F77E, $C71D, $D73C,
        $26D3, $36F2, $0691, $16B0, $6657, $7676, $4615, $5634,
        $D94C, $C96D, $F90E, $E92F, $99C8, $89E9, $B98A, $A9AB,
        $5844, $4865, $7806, $6827, $18C0, $08E1, $3882, $28A3,
        $CB7D, $DB5C, $EB3F, $FB1E, $8BF9, $9BD8, $ABBB, $BB9A,
        $4A75, $5A54, $6A37, $7A16, $0AF1, $1AD0, $2AB3, $3A92,
        $FD2E, $ED0F, $DD6C, $CD4D, $BDAA, $AD8B, $9DE8, $8DC9,
        $7C26, $6C07, $5C64, $4C45, $3CA2, $2C83, $1CE0, $0CC1,
        $EF1F, $FF3E, $CF5D, $DF7C, $AF9B, $BFBA, $8FD9, $9FF8,
        $6E17, $7E36, $4E55, $5E74, $2E93, $3EB2, $0ED1, $1EF0);
     
    var
     i: integer;
     crc: Word;
    begin
      crc := $FFFF;
      for i:=0 to len do
      begin
        crc:=  (crc shl 8) xor Crc16Table[(crc shr 8) xor pcBlock[i]];
      end;
       Result := crc;
    end;


Вроде так, но всё равно не та сумма ...?

Автор: andrew.virus 28.03.12, 14:51
User32, посмотри пример рассчета CRC16 с использованием Delphi, приведенный здесь ... проверил его работает правильно ;)

Автор: Pavia 28.03.12, 15:39
CRC бывают разные.
Первое что надо сказать про полином иногда их записывают в обратном порядке бит.

Вот взял проверил

CRC16 c классическим полиномом=22E7
CRC32 с классический полиномом=1A2FD79B
Выборочные полиномы CRC
CRC16 полином $8005=22E7
CRC32 полином $04C11DB7 =1A2FD79B
CRC16CCITT ошибочный CCITT=7952
CRC16CCITTG правильный CCITT=8551
CRC30 полином $6030B9C7 =3877E0B2
реверсирование полинома полином $EDB88320 =4C11DB7
реверсирование полинома полином $8005 =A001
реверсирование полинома полином $1021 =8408

Как видно из теста правильный результат дал классический 32 битный полином из которого взяли младшие два байта.

А вот мой код для проверки различных CRC.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Math;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    type
     TCRC=
      record
      bit:byte;
      Poly:DWord;
      Init,XorOut:Dword;
      ReflIn,ReflOut:boolean;
      end;
    var
      Form1: TForm1;
      test:array [0..8] of char=('1','2','3','4','5','6','7','8','9');
      test2:array [0..3]of byte=($11,$22,$33,$44);
      testCRC16:Word=$BB3D;
      testCRC16CCITT:Word=$29B1;
      testCRC16CCITTG:Word=$E5CC; {init=1D0F}
      testCRC32:DWord=$CBF43926;
      tabelCRC:array [0..$FF] of DWord;
      tabelCRC16:array [0..$FF] of Word =
      ($0000,$C0C1,$C181,$0140,$C301,$03C0,$0280,$C241
      ,$C601,$06C0,$0780,$C741,$0500,$C5C1,$C481,$0440
      ,$CC01,$0CC0,$0D80,$CD41,$0F00,$CFC1,$CE81,$0E40
      ,$0A00,$CAC1,$CB81,$0B40,$C901,$09C0,$0880,$C841
      ,$D801,$18C0,$1980,$D941,$1B00,$DBC1,$DA81,$1A40
      ,$1E00,$DEC1,$DF81,$1F40,$DD01,$1DC0,$1C80,$DC41
      ,$1400,$D4C1,$D581,$1540,$D701,$17C0,$1680,$D641
      ,$D201,$12C0,$1380,$D341,$1100,$D1C1,$D081,$1040
      ,$F001,$30C0,$3180,$F141,$3300,$F3C1,$F281,$3240
      ,$3600,$F6C1,$F781,$3740,$F501,$35C0,$3480,$F441
      ,$3C00,$FCC1,$FD81,$3D40,$FF01,$3FC0,$3E80,$FE41
      ,$FA01,$3AC0,$3B80,$FB41,$3900,$F9C1,$F881,$3840
      ,$2800,$E8C1,$E981,$2940,$EB01,$2BC0,$2A80,$EA41
      ,$EE01,$2EC0,$2F80,$EF41,$2D00,$EDC1,$EC81,$2C40
      ,$E401,$24C0,$2580,$E541,$2700,$E7C1,$E681,$2640
      ,$2200,$E2C1,$E381,$2340,$E101,$21C0,$2080,$E041
      ,$A001,$60C0,$6180,$A141,$6300,$A3C1,$A281,$6240
      ,$6600,$A6C1,$A781,$6740,$A501,$65C0,$6480,$A441
      ,$6C00,$ACC1,$AD81,$6D40,$AF01,$6FC0,$6E80,$AE41
      ,$AA01,$6AC0,$6B80,$AB41,$6900,$A9C1,$A881,$6840
      ,$7800,$B8C1,$B981,$7940,$BB01,$7BC0,$7A80,$BA41
      ,$BE01,$7EC0,$7F80,$BF41,$7D00,$BDC1,$BC81,$7C40
      ,$B401,$74C0,$7580,$B541,$7700,$B7C1,$B681,$7640
      ,$7200,$B2C1,$B381,$7340,$B101,$71C0,$7080,$B041
      ,$5000,$90C1,$9181,$5140,$9301,$53C0,$5280,$9241
      ,$9601,$56C0,$5780,$9741,$5500,$95C1,$9481,$5440
      ,$9C01,$5CC0,$5D80,$9D41,$5F00,$9FC1,$9E81,$5E40
      ,$5A00,$9AC1,$9B81,$5B40,$9901,$59C0,$5880,$9841
      ,$8801,$48C0,$4980,$8941,$4B00,$8BC1,$8A81,$4A40
      ,$4E00,$8EC1,$8F81,$4F40,$8D01,$4DC0,$4C80,$8C41
      ,$4400,$84C1,$8581,$4540,$8701,$47C0,$4680,$8641
      ,$8201,$42C0,$4380,$8341,$4100,$81C1,$8081,$4040);
      tabelCRC32:array [0..$FF] of DWord =
      ($00000000,$77073096,$EE0E612C,$990951BA
      ,$076DC419,$706AF48F,$E963A535,$9E6495A3
      ,$0EDB8832,$79DCB8A4,$E0D5E91E,$97D2D988
      ,$09B64C2B,$7EB17CBD,$E7B82D07,$90BF1D91
      ,$1DB71064,$6AB020F2,$F3B97148,$84BE41DE
      ,$1ADAD47D,$6DDDE4EB,$F4D4B551,$83D385C7
      ,$136C9856,$646BA8C0,$FD62F97A,$8A65C9EC
      ,$14015C4F,$63066CD9,$FA0F3D63,$8D080DF5
      ,$3B6E20C8,$4C69105E,$D56041E4,$A2677172
      ,$3C03E4D1,$4B04D447,$D20D85FD,$A50AB56B
      ,$35B5A8FA,$42B2986C,$DBBBC9D6,$ACBCF940
      ,$32D86CE3,$45DF5C75,$DCD60DCF,$ABD13D59
      ,$26D930AC,$51DE003A,$C8D75180,$BFD06116
      ,$21B4F4B5,$56B3C423,$CFBA9599,$B8BDA50F
      ,$2802B89E,$5F058808,$C60CD9B2,$B10BE924
      ,$2F6F7C87,$58684C11,$C1611DAB,$B6662D3D
      ,$76DC4190,$01DB7106,$98D220BC,$EFD5102A
      ,$71B18589,$06B6B51F,$9FBFE4A5,$E8B8D433
      ,$7807C9A2,$0F00F934,$9609A88E,$E10E9818
      ,$7F6A0DBB,$086D3D2D,$91646C97,$E6635C01
      ,$6B6B51F4,$1C6C6162,$856530D8,$F262004E
      ,$6C0695ED,$1B01A57B,$8208F4C1,$F50FC457
      ,$65B0D9C6,$12B7E950,$8BBEB8EA,$FCB9887C
      ,$62DD1DDF,$15DA2D49,$8CD37CF3,$FBD44C65
      ,$4DB26158,$3AB551CE,$A3BC0074,$D4BB30E2
      ,$4ADFA541,$3DD895D7,$A4D1C46D,$D3D6F4FB
      ,$4369E96A,$346ED9FC,$AD678846,$DA60B8D0
      ,$44042D73,$33031DE5,$AA0A4C5F,$DD0D7CC9
      ,$5005713C,$270241AA,$BE0B1010,$C90C2086
      ,$5768B525,$206F85B3,$B966D409,$CE61E49F
      ,$5EDEF90E,$29D9C998,$B0D09822,$C7D7A8B4
      ,$59B33D17,$2EB40D81,$B7BD5C3B,$C0BA6CAD
      ,$EDB88320,$9ABFB3B6,$03B6E20C,$74B1D29A
      ,$EAD54739,$9DD277AF,$04DB2615,$73DC1683
      ,$E3630B12,$94643B84,$0D6D6A3E,$7A6A5AA8
      ,$E40ECF0B,$9309FF9D,$0A00AE27,$7D079EB1
      ,$F00F9344,$8708A3D2,$1E01F268,$6906C2FE
      ,$F762575D,$806567CB,$196C3671,$6E6B06E7
      ,$FED41B76,$89D32BE0,$10DA7A5A,$67DD4ACC
      ,$F9B9DF6F,$8EBEEFF9,$17B7BE43,$60B08ED5
      ,$D6D6A3E8,$A1D1937E,$38D8C2C4,$4FDFF252
      ,$D1BB67F1,$A6BC5767,$3FB506DD,$48B2364B
      ,$D80D2BDA,$AF0A1B4C,$36034AF6,$41047A60
      ,$DF60EFC3,$A867DF55,$316E8EEF,$4669BE79
      ,$CB61B38C,$BC66831A,$256FD2A0,$5268E236
      ,$CC0C7795,$BB0B4703,$220216B9,$5505262F
      ,$C5BA3BBE,$B2BD0B28,$2BB45A92,$5CB36A04
      ,$C2D7FFA7,$B5D0CF31,$2CD99E8B,$5BDEAE1D
      ,$9B64C2B0,$EC63F226,$756AA39C,$026D930A
      ,$9C0906A9,$EB0E363F,$72076785,$05005713
      ,$95BF4A82,$E2B87A14,$7BB12BAE,$0CB61B38
      ,$92D28E9B,$E5D5BE0D,$7CDCEFB7,$0BDBDF21
      ,$86D3D2D4,$F1D4E242,$68DDB3F8,$1FDA836E
      ,$81BE16CD,$F6B9265B,$6FB077E1,$18B74777
      ,$88085AE6,$FF0F6A70,$66063BCA,$11010B5C
      ,$8F659EFF,$F862AE69,$616BFFD3,$166CCF45
      ,$A00AE278,$D70DD2EE,$4E048354,$3903B3C2
      ,$A7672661,$D06016F7,$4969474D,$3E6E77DB
      ,$AED16A4A,$D9D65ADC,$40DF0B66,$37D83BF0
      ,$A9BCAE53,$DEBB9EC5,$47B2CF7F,$30B5FFE9
      ,$BDBDF21C,$CABAC28A,$53B39330,$24B4A3A6
      ,$BAD03605,$CDD70693,$54DE5729,$23D967BF
      ,$B3667A2E,$C4614AB8,$5D681B02,$2A6F2B94
      ,$B40BBE37,$C30C8EA1,$5A05DF1B,$2D02EF8D);
    implementation
     
    {$R *.dfm}
    function GetCRC32(p:pointer;length:integer):DWord;
    var b1,b2:byte;
    crc:DWord;
    var i:integer;
    begin
    CRC:=$FFFFFFFF;
    for i:=0 to length-1 do
     begin
     CRC:= (CRC shr 8) xor TabelCRC32[byte(CRC) xor Byte(PChar(p)[i])];
     end;
    CRC:=CRC xor $FFFFFFFF;
    GetCRC32:=CRC;
    end;
     
    function GetCRC16(p:pointer;length:integer):Word;
    var b1,b2:byte;
    crc:Word;
    var i:integer;
    begin
    CRC:=0;
    for i:=0 to length-1 do
     begin
     CRC:= (CRC shr 8) xor TabelCRC16[byte(CRC) xor Byte(PChar(p)[i])];
     end;
    CRC:=CRC xor $0;
    GetCRC16:=CRC;
    end;
     
    function revers(w:DWord; j:integer):DWord;
    var i:integer;
    p:DWord;
    begin
    p:=0;
    for i:=1 to j do
     begin
     if w and 1<>0 then   p:=(p shl 1) or 1 else p:=(p shl 1);
     w:=w shr 1;
     end;
    revers:=p;
    end;
     
    function CRC(bit:byte;Poly:DWord; Init,XorOut:Dword;ReflIn,ReflOut:boolean):TCRC;
    begin
    Result.Init:=Init;
    Result.XorOut:=XorOut;
    Result.Poly:=Poly;
    Result.bit:=bit;
    Result.ReflIn:=ReflIn;
    Result.ReflOut:=ReflOut;
    end;
     
    procedure CreatTableCRC(T:TCRC;Tabel:Pointer);
    type
     TTable=array [0..0] of DWord;
     PTable=^TTable;
    var
      i, j: Word;
      crc: DWord;
    begin
    if (t.ReflIn) then
     begin
     t.Poly:=revers(t.Poly,t.bit);
      for i := 0 to 255 do
       begin
       crc := i;
       for j := 0 to 7 do
          if (crc and 1) <> 0 then
            crc := (crc shr 1) xor t.Poly
          else
            crc := (crc shr 1);
        PTable(Tabel)[i] := crc;
       end;
     end else
     begin
      for i := 0 to 255 do
       begin
       crc := i shl (t.bit-8);
       for j := 0 to 7 do
          if (crc and (1 shl (t.bit-1))) <> 0 then
            crc := (crc shl 1) xor t.Poly
          else
            crc := (crc shl 1);
        PTable(Tabel)[i] := crc  mod (1 shl t.bit);
       end;
     end;
    end;
     
    function GetCRC(t:TCRC;p:pointer;length:integer;Tabel:Pointer):DWord;
    type
     TTable=array [0..0] of DWord;
     PTable=^TTable;
    var
    crc:DWord;
    i:integer;
    begin
     CRC:=t.Init;
    if (t.ReflIn) then
     for i:=0 to length-1 do
      CRC:= (CRC shr 8) xor PTable(Tabel)[byte(CRC) xor Byte(PChar(p)[i])]
     else
     begin
     for i:=0 to length-1 do
      CRC:= (CRC shl 8) xor PTable(Tabel)[byte(CRC shr (t.bit-8)) xor Byte(PChar(p)[i])];
     end;
    CRC:=CRC xor t.XorOut;
    if (t.ReflOut xor  t.ReflIn) then   CRC:=revers(CRC,t.bit);
    GetCRC:=CRC shl (32-t.bit) shr (32-t.bit);
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var c1,c2,c3,c4,c5:DWord;
    t:TCRC;
    begin
    memo1.Text:='';
    c1:=GetCRC16(@Test,Length(Test));
    c2:=GetCRC32(@Test,Length(Test));
    t:=CRC(16,$8005,$0,$0,true,true);
    CreatTableCRC(t,@TabelCRC);
    c3:=GetCRC(t,@Test,Length(Test),@TabelCRC);
    t:=CRC(32,$04C11DB7,$FFFFFFFF,$FFFFFFFF,true,true);
    CreatTableCRC(t,@TabelCRC);
    c4:=GetCRC(t,@Test,Length(Test),@TabelCRC);
    if c1=TestCRC16 then memo1.Lines.Add('CRC16=OK');
    if c2=TestCRC32 then memo1.Lines.Add('CRC32=OK');
    memo1.Lines.Add('Custom CRC');
    if c3=TestCRC16 then memo1.Lines.Add('CRC16=OK');
    if c4=TestCRC32 then memo1.Lines.Add('CRC32=OK');
     
    t:=CRC(16,$1021,$FFFF,$0,false,false);
    CreatTableCRC(t,@TabelCRC);
    c3:=GetCRC(t,@Test,Length(Test),@TabelCRC);
    if c3=testCRC16CCITT then memo1.Lines.Add('CRC16CCITT=OK');
     
    t:=CRC(16,$1021,$1D0F,$0,false,false);
    CreatTableCRC(t,@TabelCRC);
    c4:=GetCRC(t,@Test,Length(Test),@TabelCRC);
    if c4=testCRC16CCITTG then  memo1.Lines.Add('CRC16CCITTG=OK');
     
    t:=CRC(30,$6030B9C7,$3FFFFFFF,$0,True,True);
    CreatTableCRC(t,@TabelCRC);
    c5:=GetCRC(t,@Test,Length(Test),@TabelCRC);
    memo1.Lines.Add(format('%X',[c5]));
     
    t:=CRC(32,$4C11DB7,$FFFFFFFF,$FFFFFFFF,true,true);
    CreatTableCRC(t,@TabelCRC);
    c5:=GetCRC(t,@Test2,4,@TabelCRC);
    memo1.Lines.Add(format('%X',[c5]));
     
     
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
    c1,c2,c3,c4,c5:DWord;
    t:TCRC;
    test:String;
    begin
    test:=#$73#$48#$00#$0D#$00#$00#$00#$00#$00#$00#$00;
    memo1.Text:='';
    c1:=GetCRC16(@Test[1],Length(Test));
    c2:=GetCRC32(@Test[1],Length(Test));
    t:=CRC(16,$8005,$0,$0,true,true);
    CreatTableCRC(t,@TabelCRC);
    c3:=GetCRC(t,@Test[1],Length(Test),@TabelCRC);
    t:=CRC(32,$04C11DB7,$FFFFFFFF,$FFFFFFFF,true,true);
    CreatTableCRC(t,@TabelCRC);
    c4:=GetCRC(t,@Test[1],Length(Test),@TabelCRC);
     
    memo1.Lines.Add(Format('CRC16 c классическим полиномом=%.2X',[c1]));
    memo1.Lines.Add(Format('CRC32 с классический полиномом=%X',[c2]));
    memo1.Lines.Add('Custom CRC');
    memo1.Lines.Add(Format('CRC16 полином $8005=%.2X',[c1]));
    memo1.Lines.Add(Format('CRC32 полином $04C11DB7  =%X',[c2]));
     
    t:=CRC(16,$1021,$FFFF,$0,false,false);
    CreatTableCRC(t,@TabelCRC);
    c3:=GetCRC(t,@Test[1],Length(Test),@TabelCRC);
    memo1.Lines.Add(Format('CRC16CCITT ошибочный CCITT=%.2X',[c3]));
     
    t:=CRC(16,$1021,$1D0F,$0,false,false);
    CreatTableCRC(t,@TabelCRC);
    c4:=GetCRC(t,@Test[1],Length(Test),@TabelCRC);
    memo1.Lines.Add(Format('CRC16CCITTG правильный CCITT=%.2X',[c4]));
     
    t:=CRC(30,$6030B9C7,$3FFFFFFF,$0,True,True);
    CreatTableCRC(t,@TabelCRC);
    c5:=GetCRC(t,@Test[1],Length(Test),@TabelCRC);
    memo1.Lines.Add(Format('CRC30 полином $6030B9C7 =%X',[c5]));
    memo1.Lines.Add(Format('реверсирование полинома полином $EDB88320 =%X',[revers($EDB88320,32)]));
    memo1.Lines.Add(Format('реверсирование полинома полином $8005 =%.2X',[revers($8005,16)]));
    memo1.Lines.Add(Format('реверсирование полинома полином $1021 =%.2X',[revers($1021,16)]));
     
    end;
     
    end.


Ошибочным CRC CCITT считается алгоритм через таблицу. Правильный это полином по классической схеме, путем побитового деления.
В коде показано как ошибочный табличный алгоритм переделать в правильный табличный. Делается это заменой начального значения расчёта.

Автор: User32 29.03.12, 09:34
Цитата Pavia @
CRC32 с классический полиномом

Да действительно так, я у себя в алгоритме вычисления CRC32 нашёл ошибку - исправил.
Спасибо.

Автор: sierra 26.12.17, 14:21
Извиняюсь за поднятие старой темы.

Цитата User32 @
А вот мой код для проверки различных CRC.

Проверял на CRC32, при ReflIn := False в функции CreatTableCRC таблица всегда заполняется только нулями.
Может есть подправленный исходник?

Автор: sierra 27.12.17, 10:40
Изменил
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    PTable(Tabel)[i] := crc mod (1 shl T.bit);

на
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    PTable(Tabel)[i] := crc;
вроде стало правильно считать.

PS: Pavia, спасибо за код

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)