# custom crc32 calculation in python without libs

0

I have been looking for a simple python code which can generate a crc32-sum. It is for a stm32 and i dont find a good example which is adjustable.

To get the right settings for my calculation i used following side.

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

The settings would be the following:

Polynomial: 0x4C11DB7, Initial Value: 0xFFFFFFFF and no Xor Value or 0x00, also the Input and result are not reflected.

Does someone know where i could get a simple adjustable algorithm or where i can learn how to write one?

Edit: I use this function to create the table

``````def create_table():
a = []
for i in range(256):
k = i
for j in range(8):
if k & 1:
k ^= 0x4C11DB7
k >>= 1
a.append(k)
return a
``````

and the following for generating the crc-sum

``````def crc32(bytestream):
crc_table = create_table()

crc32 = 0xffffffff

for byte in range( int(len(bytestream)) ):
lookup_index = (crc32 ^ byte) & 0xff
crc32 = (crc32 >> 8) ^ crc_table[lookup_index]

return crc32
``````

and call the function with this

``````print(hex(crc32(b"1205")))
``````

the result is: 0x9f8e7b8c

but the website gives me: 0xA7D10A0A

can someone help me?

python
python-3.x
stm32
crc32

1

First off, what you have is for a reflected CRC, not a non-reflected CRC. Though there is an error in your table construction. This:

``````if k & 1:
k ^= 0x4C11DB7
k >>= 1
``````

is wrong. The exclusive-or must be done after the shift. So it would need to be (for the reflected case):

``````k = (k >> 1) ^ 0xedb88320 if k & 1 else k >> 1
``````

Note that the polynomial also needs to be reflected in this case.

Another error in your code is using `range` to make the integers 0, 1, ..., and using those instead of the actual data bytes to compute the CRC on! What you want for your for loop is simply:

``````for byte in bytestream:
``````

The whole point of using a table is to make the CRC calculation faster. You don't want to regenerate the table every time you do a CRC. You want to generate the table once when your program starts, and then use it multiple times. Or you can generate the table separately from your program, and then put the table itself in your program. That's what's usually done.

Anyway, to do the non-reflected case, you need to flip things around. So to make the table:

``````def create_table():
a = []
for i in range(256):
k = i << 24;
for _ in range(8):
k = (k << 1) ^ 0x4c11db7 if k & 0x80000000 else k << 1
a.append(k & 0xffffffff)
return a
``````

To use the table:

``````def crc32(bytestream):
crc_table = create_table()
crc = 0xffffffff
for byte in bytestream:
lookup_index = ((crc >> 24) ^ byte) & 0xff
crc = ((crc & 0xffffff) << 8) ^ crc_table[lookup_index]
return crc
``````

Now it correctly implements your specification, which happens to be the MPEG-2 32-bit CRC specification (from Greg Cook's CRC catalogue):

``````width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000 check=0x0376e6e7 residue=0x00000000 name="CRC-32/MPEG-2"
``````

For the code above, if I do:

``````print(hex(crc32(b'123456789')))
``````

I get `0x376e6e7`, which matches the check value in the catalog.

Again, you need to take the `create_table()` out of the `crc32()` routine and do it somewhere else, once.

User contributions licensed under CC BY-SA 3.0