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);
        escribetragados(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 ) 
        init_crcccitt_tab();
    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 );
            ptr++;
       }
     * 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)
            Else
                $crc = BitRotate($crc,1)
            EndIf
            $c = BitRotate($c,1)
        Next
        $crc_tabccitt[$i] = $crc
    Next
    $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
EndFunc

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'      )
        EndIf
        If ( Asc($ptr[$k]) >= 'A'  AND  Asc($ptr[$k]) <= 'F' ) Then
                  $dest[$k+1] = ( ($ptr[$k]) - 'A' + 10 )
        EndIf
        If ( Asc($ptr[$k]) >= 'a'  AND  Asc($ptr[$k]) <= 'f' ) Then
                  $dest[$k+1] = ( $ptr[$k] - 'a' + 10 )
        EndIf
        $k=$k+1
WEnd
$dest[$k]   = -128     ; I founf that '\x80' in C is equal to -128
$k=$k+1
$dest[$k]   = -128
$crc        = 0xffff
$prev_byte  = 0        
$ptr  = $calcula
$k=0
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
WEnd
           
$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 !

Link to comment
Share on other sites

Hi,

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..

Regards

Link to comment
Share on other sites

  • 3 years later...

Hi,

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?

Regards

Link to comment
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
    Next
    Return '0x' & Hex($crc16, 4)                                                 ; Returns CRC16 as hexadecimal string
EndFunc   ;==>crcXmodem
Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...