I am trying to use zlib.crc32
to compute CRC in Python.
I would like to be able to set the generator polynomial of the CRC, but I cannot find any documentation. So the question is: can this be done?
I know that there is crcmod
library that can do this, but in my case I want to only use standard Python libraries and don't want to install any external library. Is there any standard Python library that can be used to calculate CRC and I can define its generator polynomial?
in crcmod
it is done as:
import crcmod
crc32 = crcmod.Crc(poly=0x104c11db7, rev=True, initCrc=0, xorOut=0xFFFFFFFF)
crc32.update(bytearray(input_string))
in the above code the poly
is the generator polynomial.
No, the polynomial and other CRC parameters are hard-coded in zlib.
However the CRC-32 generated by those parameters is the CRC that zlib implements. You can just use zlib.crc32
.
>>> import crcmod
>>> crc32 = crcmod.mkCrcFun(poly=0x104c11db7, rev=True, initCrc=0, xorOut=0xFFFFFFFF)
>>> print(hex(crc32(b'123456789')))
0xcbf43926
>>> import zlib
>>> print(hex(zlib.crc32(b'123456789')))
0xcbf43926
Update:
From the comments, speed is not important, and they want a different CRC polynomial.
Here is a simple CRC-32 implementation, assuming rev=True
, for which you can change or parameterize the polynomial, the initial value, and the final exclusive-or:
def crc32(msg):
crc = 0xffffffff
for b in msg:
crc ^= b
for _ in range(8):
crc = (crc >> 1) ^ 0xedb88320 if crc & 1 else crc >> 1
return crc ^ 0xffffffff
print(hex(crc32(b'123456789')))
Prints: 0xcbf43926
.
If you need something faster, then you'd need to generate a table for a byte-wise table-driven CRC implementation.
Update:
As the original poster continues to trickle out tiny bits of information about their actual question in comments (as opposed to simply saying in total what they want to do in the question), we learn that they need to generate a forward CRC as well (rev=False
), specifically a CRC-32/MPEG-2. So here is the simple code for that:
def crc32mpeg2(msg):
crc = 0xffffffff
for b in msg:
crc ^= b << 24
for _ in range(8):
crc = (crc << 1) ^ 0x04c11db7 if crc & 0x80000000 else crc << 1
return crc & 0xffffffff
print(hex(crc32mpeg2(b'123456789')))
Prints: 0x376e6e7
.