Crcmod python3 polynomial error

2019-07-08 19:49发布

I need to use a crc checksum in a python3 program, but my knowledge of crc is virtually non-existent.

Here is the test code I wrote

import crcmod

crc_func = crcmod.mkCrcFun(0x1d, initCrc=0x07, xorOut=0x00)
print(hex(crc_func(b'123456789')))

When I run this, I get the following error:

ValueError: The degree of the polynomial must be 8, 16, 24, 32 or 64

But 1D is 8 bit, so I must be doing something wrong. Please explain what I did wrong.

1条回答
放荡不羁爱自由
2楼-- · 2019-07-08 20:37

But 1D is 8 bit

No it isn't; it's 5 bits:

>>> bin(0x1d)
'0b11101'

The way this module defines things (see the _verifyPoly function) rounds down, so this counts as a "4-bit polynomial". An "8-bit polynomial" has to be between 0x100 and 0x1ff (inclusive). Of course most of the polynomials in that range will not give useful results, but they can at least be handled by this module.


Please explain what I did wrong.

As the docs say:

The bits in this integer are the coefficients of the polynomial. The only polynomials allowed are those that generate 8, 16, 24, 32, or 64 bit CRCs.

0x1d does not generate an 8-degree polynomial.


If none of this makes any sense to you, well, the docs explicitly say, right at the top:

There is no attempt in this package to explain how the CRC works…

It is up to you to decide what polynomials to use in your application. Some common CRC algorithms are predefined in crcmod.predefined. If someone has not specified the polynomials to use, you will need to do some research to find one suitable for your application. Examples are available in the unit test script test.py.

If you don't want to learn how CRC works and figure out how to design and encode an appropriate polynomial yourself, just use one of the predefined ones.


More generally, if you don't have a specific CRC polynomial in mind, or don't even understand what this means, you probably have no reason to use this module in the first place. If you just "need to use a crc checksum", there's already a perfectly good CRC function in the stdlib, zlib.crc32.

For that matter, if it doesn't have to actually be a CRC, just a reasonably reliable checksum, you probably want zlib.adler32 instead.

Or, if adler32 and crc32 aren't sufficient for some reason, whatever that reason is, I'd wager you don't actually need a checksum but a real hash, and a better CRC polynomial isn't gong to help you; you want a different algorithm, probably something out of hashlib.

查看更多
登录 后发表回答