Computer Interfacing
Discussions about interfacing and electronics
 

CRC calculation

Can't find the right way....

Goto page Previous  1, 2
 

       Computer Interfacing Forum Index -> Error detection and correction
Author Message
asampadeh
New User



Joined: 28 Jun 2013
Posts: 4


Jun 28, 2013 8:34 am

Hi Gammabyte,

I just meet this thread recently and curious to know is CRC computation also function of input bitwidth ?
In your example the input is array element of uint8_t (8 bits).

What happened if same input but arrange in larger width ?

Instead of
{0x02,0x3F,0x00,0x00,0x00,0x00,0x00,0x00}
arrange it as
{0x023F, 0x0000, 0x0000, 0x0000}
or
{0x023F0000, 0x00000000}
or even bit representation
0000 0010 0011 1111 .... 0000

Does it matter ?
Of coz the code need to modified.

Thanks
Gammatester
Guest







Jun 28, 2013 9:57 am

@asampadeh,

I assume you mean the following situation: Leave the calculation function as is and call it with the new data (with appropriate type cast to avoid warnings).

The output depends on the endian-ness of the system. On little-endian systems the CRCs will differ. Here a test program with outputs:
Code:

#include <stdio.h>
#include <stddef.h>
#include <stdint.h>

uint16_t crcx25(const uint8_t *data, size_t len) {
  uint16_t crc = 0xFFFF;
  int i;
  if (len) do {
    crc ^= *data++;
    for (i=0; i<8; i++) {
      if (crc & 1) crc = (crc >> 1) ^ 0x8408;
      else crc >>= 1;
    }
  } while (--len);
  return(~crc);
}

int main(int argc, char *argv[])
{
  uint8_t  test2[8] = {0x02,0x3F,0x00,0x00,0x00,0x00,0x00,0x00};
  uint16_t test3[4] = {0x023F, 0x0000, 0x0000, 0x0000};
  uint16_t test4[4] = {0x3F02, 0x0000, 0x0000, 0x0000};
  uint16_t crc;
  crc = crcx25(test2, sizeof(test2));
  printf(" CRC test2:  0x%04X\n", crc);
  crc = crcx25((uint8_t *)test3, sizeof(test3));
  printf(" CRC test3:  0x%04X\n", crc);
  crc = crcx25((uint8_t *)test4, sizeof(test4));
  printf(" CRC test4:  0x%04X\n", crc);
  return 0;
}


C:\TEST>a.exe
 CRC test2:  0x47A2
 CRC test3:  0xE8F2
 CRC test4:  0x47A2

As you can see the CRC of the unswapped 16-bit data differs, and for a manual swapped 16-bit array it is the same.
asampadeh
New User



Joined: 28 Jun 2013
Posts: 4


Jun 29, 2013 4:09 am

Thanks for clarifying it. Endianness is really matter.
(1) Any specific reason why it needs uint8_t as input ?
(2) If I have 32 bytes data arranged in struct of uint32_t (Intel 32b linux)
e.g
struct indata {
uint32_t a0;
uint32_t a1;
uint32_t a2;
uint32_t a3;
}

and need to generate crc16 for the concatenation of all four a0.a1.a2.a3.
i.e
a[127:0] = a0[31:0].a1[31:0].a2[31:0].a3[31:0]

should I concat them first or proceed each uint32_t and expecting the same result (started with a3 then a2, a1, a0) ?
asampadeh
New User



Joined: 28 Jun 2013
Posts: 4


Jun 29, 2013 5:31 am

upps sorry, i shld ask this mix of data length in the struct, so instead i have:

struct indata {
uint32_t a0;
uint16_t a1;
uint16_t a2;
uint8_t a3;
};

and need to generate single crc16 for the whole four a0.a1.a2.a3.
i.e
a[71:0] = a0[31:0].a1[15:0].a2[15:0].a3[7:0]


How shld I input the data to generate crc(a)?
Gammatester
Guest







Jul 01, 2013 7:39 am

Quote:
How shld I input the data to generate crc(a)?
As long as you are working on a common base all methods will work. If you want to work on both little-endian and big-endian systems you have to specify the 'default' endian-ness. Internet and crypto specs seem to favor the big-endian format.

But there is another issue with records/structs: Alignment! If you want to be sure, you have to use (byte-)packed records, the details are compiler/system dependent. A good measure of defensive programming is to include the record length as a record field, this allows the detection of obvious alignment problems (among others).
asampadeh
New User



Joined: 28 Jun 2013
Posts: 4


Jul 03, 2013 12:36 am

Thanks for advise, i unpack the struct into uint8_t stream and it can be done.

General question, for this particular algorithm you use, I assume is bytewise method.

Do you think bitwise and bytewise implementation have similar result ? Can you share the pseudocode for both method ?
Gammatester
Guest







Jul 03, 2013 8:07 am

The code snippets in this thread are actually more or less bit-wise CRC calculations - indicated by the inner loops over the 8 bits of the data bytes. The only thing missing for a true bit-wise function is the handling of bit-lengths which are not multiples of 8.

Byte-wise algorithm normally use pre-computed tables of 256 entries. If your are looking for C implementations, do a web search for Danjel McGougan's universal_crc, with his code you can generate source for (almost) any CRC algorithm up to 64 bits.

Of course all kinds of correct implementation of X25 must give the same result at the abstract mathematical level, otherwise they would not be X25 by definition. But remember there are different representations, endian-ness etc.
behzad.west
New User



Joined: 11 Feb 2015
Posts: 1


Feb 11, 2015 10:51 am

hi, i have question like xenion.
i have tried to rebuild my function with some change..
Code:
function crcx25($data) {
   //i explode() $data and make $content array
   $content = explode(' ',$data) ;
   //i count() the array to get data length
   $len = count($content) ;
   $n = 0 ;
   
   $crc = 0xFFFF;   
   while ($len > 0)
   {
      $crc ^= $content[$n] ;
      for ($i=0; $i<8; $i++) {
         if ($crc & 1) $crc = ($crc >> 1) ^ 0x8408;
         else $crc >>= 1;
      }
      $n++ ;
      $len-- ;
   }
   
   return(~$crc);
}
//$data is substr() result from hexadecimal converted binary data using bin2hex() and i put 'space' in it.
$data = '05 01 00 01' ;
$crc25 = crcx25($data) ;

echo $crc25.'<br>' ;
echo 'crc25 = '.dechex($crc25).'<br>' ;
echo 'crc25 = '.str_replace('ffff','',dechex($crc25)).'<br>' ;

i got this result with this function
Code:
-9764
crc25 = ffffd9dc
crc25 = d9dc

it means that i have got the right crc, because it is same with the example from the communication protocol document.
Code:
//example from communication protocol
05 01 00 01 -> D9 DC

BUT, if i change the $data with other value like '05 13 00 03' or '05 13 00 11', it doesn't same with the example from the communication protocol.
Code:
//example from communication protocol
05 13 00 03 -> CA E3
05 13 00 11 -> F9 70

//the function result
05 13 00 03 -> 5f 6d
05 13 00 11 -> d3 25

anyone can tell me what happen? is my function correct?
pls write correct function.
thanks

       Computer Interfacing Forum Index -> Error detection and correction
Page 2 of 2



Running on php BB © 2001, 2009 php BB Group
   Lammert Bies     Interfacing     Sitemap     Forum