Jump to content

CRC CCITT (poly 1021) problem

Recommended Posts


Hello every body, I'm a total begginner in AutoIt and here is my first post. Hope could help me.

I have searched for all the forum about CRC, also trying to translate codes from VB to Autoit but nothing give me the right result.

I'm trying to take the CRC CCITT with poly 0x1021 in AutoIT.

The string is 0005FE0005. CRC must be FA40.

To check I'm using this web site: http://www.lammertbies.nl/comm/info/crc-calculation.html

I have it working on C, and is ok. Here is:

static void init_crcccitt_tab( void ) {
    int i, j;
    unsigned short crc, c;
    for (i=0; i<256; i++) {
        crc = 0;
        c   = ((unsigned short) i) << 8;
        //printf("i vale %i y c es: %i y ",i,c);
        for (j=0; j<8; j++) {
            if ( (crc ^ c) & 0x8000 ) { crc = ( crc << 1 ) ^ P_CCITT;  }
            else                      { crc =   crc << 1;  }
            c = c << 1;
        crc_tabccitt[i] = crc;
        //printf("y el tab es %i\n",crc);
    crc_tabccitt_init = TRUE;
}  /* init_crcccitt_tab */

unsigned short update_crc_ccitt( unsigned short crc, char c ) {

    unsigned short tmp, short_c;
    short_c  = 0x00ff & (unsigned short) c;
    printf("short_c es %i y c es %i:\n",short_c,c);
    if ( ! crc_tabccitt_init ) 
    tmp = (crc >> 8) ^ short_c;
    printf("tmp es %i:",tmp);
    crc = (crc << 8) ^ crc_tabccitt[tmp];
    printf("y crc es %i:\n",crc);
    return crc;

char *ptr, *dest, hex_val, prev_byte;
    unsigned short crc;
    char tmp[10];
    ptr  = calcula;
    dest = calcula;
    while( *ptr  &&  *ptr != '\r'  &&  *ptr != '\n' ) 
            if ( *ptr >= '0'  &&  *ptr <= '9' ) *dest++ = (char) ( (*ptr) - '0'      );
            if ( *ptr >= 'A'  &&  *ptr <= 'F' ) *dest++ = (char) ( (*ptr) - 'A' + 10 );
            if ( *ptr >= 'a'  &&  *ptr <= 'f' ) *dest++ = (char) ( (*ptr) - 'a' + 10 );
     * dest    = '\x80';
     *(dest+1) = '\x80';
        crc = 0xffff;
        prev_byte = 0;
        ptr       = calcula;
        while ( *ptr != -128 )
                hex_val  = (char) ( ( * ptr     &  '\x0f' ) << 4 );
                hex_val = hex_val | (char) ( ( *(ptr+1)  &  '\x0f' )      );              
                printf("crc vale %i y hexval es %i",crc,hex_val);
                crc = update_crc_ccitt(  crc, hex_val            );
                prev_byte = hex_val;
                ptr      += 2;
    sprintf(tmp, "%X", ~crc);

1. The translate of init_crcccitt_tab function is

Func init_crcccitt_tab($Poly = 0x1021)
    Local $c, $crc, $i, $j
    For $i = 0 To 255
        $crc = 0
        $c = BitRotate($i,8)
        For $j = 0 To 7
            If BitAND( BitXOR($crc, $c), 0x8000) Then
                $crc = BitRotate($crc,1)
                $crc = BitXOR($crc, $Poly)
                $crc = BitRotate($crc,1)
            $c = BitRotate($c,1)
        $crc_tabccitt[$i] = $crc
    $crc_tabccitt_init = True
EndFunc   ;==>crcInit

It gives me only the first 15(of 256) element of the table with the correct value. The other are a little wrong.

Ok, to resolve this I put in AutoIt the table directly with correct values from C program. Like this:

Global $crc_tabccitt[256]=[0,4129,8258..........

It is solved.

2. But the other functions are not working like in C. Here is the translate to AutoIt:

Func update_crc_ccitt($crc, $c ) 
    Dim $tmp, $short_c
    $short_c  = BitAND(0x00ff, $c)
    $tmp = BitXOR(BitRotate($crc, -8), $short_c)
    $crc = BitRotate($crc, 8)
    $crc = BitXOR($crc , $crc_tabccitt[$tmp] )
    return $crc

Dim $ptr[10], $dest[10], $hex_val, $prev_byte
Dim $crc,$tmp[10],$k=0
$ptr  = $calcula
$dest = $calcula
While( Asc($ptr[$k]) AND Asc($ptr[$k]) <> '\r' AND Asc($ptr[$k]) <> '\n' )   
        If ( Asc($ptr[$k]) >= '0'  AND  Asc($ptr[$k]) <= '9' ) Then
                  $dest[$k+1] = ( ($ptr[$k]) - '0'      )
        If ( Asc($ptr[$k]) >= 'A'  AND  Asc($ptr[$k]) <= 'F' ) Then
                  $dest[$k+1] = ( ($ptr[$k]) - 'A' + 10 )
        If ( Asc($ptr[$k]) >= 'a'  AND  Asc($ptr[$k]) <= 'f' ) Then
                  $dest[$k+1] = ( $ptr[$k] - 'a' + 10 )
$dest[$k]   = -128     ; I founf that '\x80' in C is equal to -128
$dest[$k]   = -128
$crc        = 0xffff
$prev_byte  = 0        
$ptr  = $calcula
While ( $ptr[$k] <> -128 ) 
        $hex_val  =  BitRotate(BitAND($ptr[$k],15),4)
        $hex_val  = BitOR($hex_val,  BitAND($ptr[$k+1],15))     
        $crc = update_crc_ccitt(  $crc, $hex_val)
        $prev_byte = $hex_val
        $k = $k + 2
$crc = StringRight(Hex($crc-2*$crc), 4)   ; It is to have the 2Complement 
MsgBox(0,"kk","CRC must be FA40. The result is :" & $crc)

Please could somebody take a look and see what in the translate is wrong.

Thanks all !

Share this post

Link to post
Share on other sites


at the end and because there are not much time, I put the C function into a dll :huh2:.

It is about 0.5MB in zip format, too big to attach, if anybody wants it, let me know.

It is working, but I would like the other way..


Share this post

Link to post
Share on other sites


I tried to implement a CRC16 - CCITT (xModem) algorithm in AutoIt to no avail, as my understanding is not sufficient. So I found your post here. If you are still around, could you provide me with the dll and explain me how to use it from within an AutoIt script?


Share this post

Link to post
Share on other sites

I tried to implement a CRC16 - CCITT (xModem) algorithm in AutoIt to no avail, 

you put me to work, wassup with you !, anyways, there you go :)

ConsoleWrite(crcXmodem('123456789') & @CRLF) ; Generated CRC: 0x29B1
Func crcXmodem($str)
    Local Static $CRC16_Lookup[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]

    Local $t, $crc16 = 0xFFFF ; CRC seed
    Local $len = StringLen($str)
    For $i = 1 To $len
        $t = BitXOR(BitShift($crc16, 8), Asc(StringMid($str, $i, 1)))            ; High byte Xor Message Byte to get index
        $crc16 = BitXOR(BitAND(BitShift($crc16, -8), 0xFFFF), $CRC16_Lookup[$t]) ; Update the CRC from table
    Return '0x' & Hex($crc16, 4)                                                 ; Returns CRC16 as hexadecimal string
EndFunc   ;==>crcXmodem
Edited by argumentum

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.