WORD Check_Sum( BYTE *Buf, BYTE Len )
{
WORD CRC; CRC = 0xFFFF;
while( Len-- )
        CRC = FCS(CRC, *Buf++); return ( CRC^0xFFFF );
}WORD FCS( WORD FCS_D, BYTE Da )
{
static WORD xdata FcsTab[256] = 
{
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
WORD XOR_D; XOR_D = FCS_D;
XOR_D ^= Da;
return ( (FCS_D >> 8) ^ FcsTab[XOR_D & 0x00FF] );
}

解决方案 »

  1.   

    CRC16目前常用的有两种算法,应该按下面的代码把码表换掉就可以了(没有做测试).
    function CRC16(CRC: Word; Data: Pointer; DataSize: LongWord): Word; assembler;
    asm
             AND    EDX,EDX
             JZ     @Exit
             AND    ECX,ECX
             JLE    @Exit
             PUSH   EBX
             PUSH   EDI
             XOR    EBX,EBX
             LEA    EDI,CS:[OFFSET @CRC16]
    @Start:  MOV    BL,[EDX]
             XOR    BL,AL
             SHR    AX,8
             XOR    AX,[EDI + EBX * 2]
             INC    EDX
             DEC    ECX
             JNZ    @Start
             POP    EDI
             POP    EBX
    @Exit:   RET
             NOP
    @CRC16:  DW     00000h, 0C0C1h, 0C181h, 00140h, 0C301h, 003C0h, 00280h, 0C241h
             DW     0C601h, 006C0h, 00780h, 0C741h, 00500h, 0C5C1h, 0C481h, 00440h
             DW     0CC01h, 00CC0h, 00D80h, 0CD41h, 00F00h, 0CFC1h, 0CE81h, 00E40h
             DW     00A00h, 0CAC1h, 0CB81h, 00B40h, 0C901h, 009C0h, 00880h, 0C841h
             DW     0D801h, 018C0h, 01980h, 0D941h, 01B00h, 0DBC1h, 0DA81h, 01A40h
             DW     01E00h, 0DEC1h, 0DF81h, 01F40h, 0DD01h, 01DC0h, 01C80h, 0DC41h
             DW     01400h, 0D4C1h, 0D581h, 01540h, 0D701h, 017C0h, 01680h, 0D641h
             DW     0D201h, 012C0h, 01380h, 0D341h, 01100h, 0D1C1h, 0D081h, 01040h
             DW     0F001h, 030C0h, 03180h, 0F141h, 03300h, 0F3C1h, 0F281h, 03240h
             DW     03600h, 0F6C1h, 0F781h, 03740h, 0F501h, 035C0h, 03480h, 0F441h
             DW     03C00h, 0FCC1h, 0FD81h, 03D40h, 0FF01h, 03FC0h, 03E80h, 0FE41h
             DW     0FA01h, 03AC0h, 03B80h, 0FB41h, 03900h, 0F9C1h, 0F881h, 03840h
             DW     02800h, 0E8C1h, 0E981h, 02940h, 0EB01h, 02BC0h, 02A80h, 0EA41h
             DW     0EE01h, 02EC0h, 02F80h, 0EF41h, 02D00h, 0EDC1h, 0EC81h, 02C40h
             DW     0E401h, 024C0h, 02580h, 0E541h, 02700h, 0E7C1h, 0E681h, 02640h
             DW     02200h, 0E2C1h, 0E381h, 02340h, 0E101h, 021C0h, 02080h, 0E041h
             DW     0A001h, 060C0h, 06180h, 0A141h, 06300h, 0A3C1h, 0A281h, 06240h
             DW     06600h, 0A6C1h, 0A781h, 06740h, 0A501h, 065C0h, 06480h, 0A441h
             DW     06C00h, 0ACC1h, 0AD81h, 06D40h, 0AF01h, 06FC0h, 06E80h, 0AE41h
             DW     0AA01h, 06AC0h, 06B80h, 0AB41h, 06900h, 0A9C1h, 0A881h, 06840h
             DW     07800h, 0B8C1h, 0B981h, 07940h, 0BB01h, 07BC0h, 07A80h, 0BA41h
             DW     0BE01h, 07EC0h, 07F80h, 0BF41h, 07D00h, 0BDC1h, 0BC81h, 07C40h
             DW     0B401h, 074C0h, 07580h, 0B541h, 07700h, 0B7C1h, 0B681h, 07640h
             DW     07200h, 0B2C1h, 0B381h, 07340h, 0B101h, 071C0h, 07080h, 0B041h
             DW     05000h, 090C1h, 09181h, 05140h, 09301h, 053C0h, 05280h, 09241h
             DW     09601h, 056C0h, 05780h, 09741h, 05500h, 095C1h, 09481h, 05440h
             DW     09C01h, 05CC0h, 05D80h, 09D41h, 05F00h, 09FC1h, 09E81h, 05E40h
             DW     05A00h, 09AC1h, 09B81h, 05B40h, 09901h, 059C0h, 05880h, 09841h
             DW     08801h, 048C0h, 04980h, 08941h, 04B00h, 08BC1h, 08A81h, 04A40h
             DW     04E00h, 08EC1h, 08F81h, 04F40h, 08D01h, 04DC0h, 04C80h, 08C41h
             DW     04400h, 084C1h, 08581h, 04540h, 08701h, 047C0h, 04680h, 08641h
             DW     08201h, 042C0h, 04380h, 08341h, 04100h, 081C1h, 08081h, 04040h
    end;
      

  2.   

    手工转的,和C的结果是一致的function FCS( FCS_D:WORD ;  Da:Byte ):Word;
    var
      XOR_D:Word;
      const FcsTab:array[0..255]of Word =(
        $0000, $1189, $2312, $329b, $4624, $57ad, $6536, $74bf,
        $8c48, $9dc1, $af5a, $bed3, $ca6c, $dbe5, $e97e, $f8f7,
        $1081, $0108, $3393, $221a, $56a5, $472c, $75b7, $643e,
        $9cc9, $8d40, $bfdb, $ae52, $daed, $cb64, $f9ff, $e876,
        $2102, $308b, $0210, $1399, $6726, $76af, $4434, $55bd,
        $ad4a, $bcc3, $8e58, $9fd1, $eb6e, $fae7, $c87c, $d9f5,
        $3183, $200a, $1291, $0318, $77a7, $662e, $54b5, $453c,
        $bdcb, $ac42, $9ed9, $8f50, $fbef, $ea66, $d8fd, $c974,
        $4204, $538d, $6116, $709f, $0420, $15a9, $2732, $36bb,
        $ce4c, $dfc5, $ed5e, $fcd7, $8868, $99e1, $ab7a, $baf3,
        $5285, $430c, $7197, $601e, $14a1, $0528, $37b3, $263a,
        $decd, $cf44, $fddf, $ec56, $98e9, $8960, $bbfb, $aa72,
        $6306, $728f, $4014, $519d, $2522, $34ab, $0630, $17b9,
        $ef4e, $fec7, $cc5c, $ddd5, $a96a, $b8e3, $8a78, $9bf1,
        $7387, $620e, $5095, $411c, $35a3, $242a, $16b1, $0738,
        $ffcf, $ee46, $dcdd, $cd54, $b9eb, $a862, $9af9, $8b70,
        $8408, $9581, $a71a, $b693, $c22c, $d3a5, $e13e, $f0b7,
        $0840, $19c9, $2b52, $3adb, $4e64, $5fed, $6d76, $7cff,
        $9489, $8500, $b79b, $a612, $d2ad, $c324, $f1bf, $e036,
        $18c1, $0948, $3bd3, $2a5a, $5ee5, $4f6c, $7df7, $6c7e,
        $a50a, $b483, $8618, $9791, $e32e, $f2a7, $c03c, $d1b5,
        $2942, $38cb, $0a50, $1bd9, $6f66, $7eef, $4c74, $5dfd,
        $b58b, $a402, $9699, $8710, $f3af, $e226, $d0bd, $c134,
        $39c3, $284a, $1ad1, $0b58, $7fe7, $6e6e, $5cf5, $4d7c,
        $c60c, $d785, $e51e, $f497, $8028, $91a1, $a33a, $b2b3,
        $4a44, $5bcd, $6956, $78df, $0c60, $1de9, $2f72, $3efb,
        $d68d, $c704, $f59f, $e416, $90a9, $8120, $b3bb, $a232,
        $5ac5, $4b4c, $79d7, $685e, $1ce1, $0d68, $3ff3, $2e7a,
        $e70e, $f687, $c41c, $d595, $a12a, $b0a3, $8238, $93b1,
        $6b46, $7acf, $4854, $59dd, $2d62, $3ceb, $0e70, $1ff9,
        $f78f, $e606, $d49d, $c514, $b1ab, $a022, $92b9, $8330,
        $7bc7, $6a4e, $58d5, $495c, $3de3, $2c6a, $1ef1, $0f78 );
    begin
      XOR_D := FCS_D xor Da;
      result := ( FCS_D shr 8 ) xor FcsTab[ XOR_D and $ff ];
    end;
    function Check_Sum( Buf:PByte;Len:Byte):Word;
    var
      crc:Word;
    begin
      crc := $ffff;
      while Len>0 do
      begin
        crc := FCS( crc , Buf^ );
        Inc(Buf);
        dec(Len);
      end;
      result := crc xor $ffff;
    end;
      

  3.   

    function CRC16(CRC: Word; Data: Pointer; DataSize: LongWord): Word; assembler;
    asm
             AND    EDX,EDX
             JZ     @Exit
             AND    ECX,ECX
             JLE    @Exit
             PUSH   EBX
             PUSH   EDI
             LEA    EDI,CS:[OFFSET @CRC16]
    @Start:  XOR    EBX,EBX
             MOV    BL,[EDX]
             XOR    BX,AX
             SHR    AX,8
             and    BX,0ffh
             MOV    BX,[EDI + EBX * 2]
             XOR    AX,BX
             INC    EDX
             DEC    ECX
             JNZ    @Start
             XOR    AX,0ffffh
             POP    EDI
             POP    EBX
    @Exit:   RET
             NOP
    @CRC16:  DW     00000h, 01189h, 02312h, 0329bh, 04624h, 057adh, 06536h, 074bfh
             DW     08c48h, 09dc1h, 0af5ah, 0bed3h, 0ca6ch, 0dbe5h, 0e97eh, 0f8f7h
             DW     01081h, 00108h, 03393h, 0221ah, 056a5h, 0472ch, 075b7h, 0643eh
             DW     09cc9h, 08d40h, 0bfdbh, 0ae52h, 0daedh, 0cb64h, 0f9ffh, 0e876h
             DW     02102h, 0308bh, 00210h, 01399h, 06726h, 076afh, 04434h, 055bdh
             DW     0ad4ah, 0bcc3h, 08e58h, 09fd1h, 0eb6eh, 0fae7h, 0c87ch, 0d9f5h
             DW     03183h, 0200ah, 01291h, 00318h, 077a7h, 0662eh, 054b5h, 0453ch
             DW     0bdcbh, 0ac42h, 09ed9h, 08f50h, 0fbefh, 0ea66h, 0d8fdh, 0c974h
             DW     04204h, 0538dh, 06116h, 0709fh, 00420h, 015a9h, 02732h, 036bbh
             DW     0ce4ch, 0dfc5h, 0ed5eh, 0fcd7h, 08868h, 099e1h, 0ab7ah, 0baf3h
             DW     05285h, 0430ch, 07197h, 0601eh, 014a1h, 00528h, 037b3h, 0263ah
             DW     0decdh, 0cf44h, 0fddfh, 0ec56h, 098e9h, 08960h, 0bbfbh, 0aa72h
             DW     06306h, 0728fh, 04014h, 0519dh, 02522h, 034abh, 00630h, 017b9h
             DW     0ef4eh, 0fec7h, 0cc5ch, 0ddd5h, 0a96ah, 0b8e3h, 08a78h, 09bf1h
             DW     07387h, 0620eh, 05095h, 0411ch, 035a3h, 0242ah, 016b1h, 00738h
             DW     0ffcfh, 0ee46h, 0dcddh, 0cd54h, 0b9ebh, 0a862h, 09af9h, 08b70h
             DW     08408h, 09581h, 0a71ah, 0b693h, 0c22ch, 0d3a5h, 0e13eh, 0f0b7h
             DW     00840h, 019c9h, 02b52h, 03adbh, 04e64h, 05fedh, 06d76h, 07cffh
             DW     09489h, 08500h, 0b79bh, 0a612h, 0d2adh, 0c324h, 0f1bfh, 0e036h
             DW     018c1h, 00948h, 03bd3h, 02a5ah, 05ee5h, 04f6ch, 07df7h, 06c7eh
             DW     0a50ah, 0b483h, 08618h, 09791h, 0e32eh, 0f2a7h, 0c03ch, 0d1b5h
             DW     02942h, 038cbh, 00a50h, 01bd9h, 06f66h, 07eefh, 04c74h, 05dfdh
             DW     0b58bh, 0a402h, 09699h, 08710h, 0f3afh, 0e226h, 0d0bdh, 0c134h
             DW     039c3h, 0284ah, 01ad1h, 00b58h, 07fe7h, 06e6eh, 05cf5h, 04d7ch
             DW     0c60ch, 0d785h, 0e51eh, 0f497h, 08028h, 091a1h, 0a33ah, 0b2b3h
             DW     04a44h, 05bcdh, 06956h, 078dfh, 00c60h, 01de9h, 02f72h, 03efbh
             DW     0d68dh, 0c704h, 0f59fh, 0e416h, 090a9h, 08120h, 0b3bbh, 0a232h
             DW     05ac5h, 04b4ch, 079d7h, 0685eh, 01ce1h, 00d68h, 03ff3h, 02e7ah
             DW     0e70eh, 0f687h, 0c41ch, 0d595h, 0a12ah, 0b0a3h, 08238h, 093b1h
             DW     06b46h, 07acfh, 04854h, 059ddh, 02d62h, 03cebh, 00e70h, 01ff9h
             DW     0f78fh, 0e606h, 0d49dh, 0c514h, 0b1abh, 0a022h, 092b9h, 08330h
             DW     07bc7h, 06a4eh, 058d5h, 0495ch, 03de3h, 02c6ah, 01ef1h, 00f78h
    end;
    测试代码
    var
      str: String;
    begin
      str:= '测试';
    ShowMessage(IntToStr(CRC16($ffff,PChar(str),Length(str))));
      

  4.   

    汇编是为了加速.你写Delphi的代码最终生成的跟汇编的啥区别.如果你仅只是为了应用这无关紧要.在Delphi当中众多工具函数为了效率都会使用汇编代码.
      

  5.   

    四楼的大哥,好像不对似的...内容:4040120013751395515FFF410101
    检验:F87C内容:4040120013713469138FFF410101
    检验:98BA上面是两组对应的内容和校验,用你的方法得到的结果不一样的???
    是不是哪里错了呢???
      

  6.   

    4040120013751395515FFF410101
    这是一个十六进制串还是文本串?
      

  7.   

    不知道你是如何测试的...var
      str: String;
    begin
      str:= #$40#$40#$12#$00#$13#$75#$13#$95#$51#$5F#$FF#$41#$01#$01;
    ShowMessage(IntToHex(Check_Sum(PByte(PChar(str)),Length(str)),4));end;
      

  8.   

    得出来的结果在X86系统上面,由于Word类型有一个字节序问题,所以得到的是7CF8,即#$F8#$7C.