CRC32 Mpeg checksums don't match?


I've been trying to reverse engineer a crc32 checksum. I don't have access to the original J# code as it is compiled and decompiling it has not been helpful. I ran 10 payloads through reveng which returned:

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

I tried running the packages through two different python libraries and even constructed an objective-c algorithm to try to get the known checksums. The recreations all matched each other, but they did not match the original checksums. Any ideas?

Here are the original and calculated crc32 checksums:

original  -> calculated

1.  0x99c93052 -> 0x13bc2c5c
2.  0xb5cea403 -> 0x1fd00c8e
3.  0xc7e4f40c -> 0xf9698bd6
4.  0xabe5ad28 -> 0x6be300d6
5.  0x2dacbf16 -> 0x43b2c356
6.  0xf321c2E9 -> 0xacb5981a
7.  0x01430cb6 -> 0x2f9e64ee
8.  0xa1028afb -> 0x44c7182b
9.  0xe73118e6 -> 0xd6c1ffa5
10. 0x5f366305 -> 0x84961d17

Any and all suggestions are appreciated!


As per request here are original payloads with their CRC-32/MPEG-2 checksum and their calculated checksum:

1. Payload = d3b09900005500005469746c653a090954657374207469746c652020202020202020202020202020202020202020202020202020202020200a4172746973743a09095465737420617274697374202020202020202020202020202020202020200a43443a0909095465737420434420202020202020202020202020202020202020202020200a4c6162656c3a0954657374204c626c202000
   Orig = 0xf9297a54
   Calc = 0xebcc0d91
2. Payload = d3b09900004300005469746c653a090954657374207469746c652032202020202020202020202020202020202020202020202020202020200a4172746973743a09095465737420617274697374202020202020202020202020202020202020200a43443a0909095465737420434420202020202020202020202020202020202020202020200a4c6162656c3a0954657374204c626c202000
   Orig = 0xb518dad0
   Calc = 0x45e4e895
3. Payload = d3b09900004300005469746c653a090954657374207469746c652033202020202020202020202020202020202020202020202020202020200a4172746973743a09095465737420617274697374202020202020202020202020202020202020200a43443a0909095465737420434420202020202020202020202020202020202020202020200a4c6162656c3a0954657374204c626c202000
   Orig = 0xe367073b
   Calc = 0x5db5800c
4. Payload = d3b09900004300005469746c653a090954657374207469746c652034202020202020202020202020202020202020202020202020202020200a4172746973743a09095465737420617274697374202020202020202020202020202020202020200a43443a0909095465737420434420202020202020202020202020202020202020202020200a4c6162656c3a0954657374204c626c202000
   Orig = 0x44d90b1d
   Calc = 0x14039bc3

This is one way I calculated those checksums (although pycrc and the objective-c code I implemented all gave the same results):

>>> import crcmod.predefined
>>> s = 'd3b09900004300005469746c653a090954657374207469746c652034202020202020202020202020202020202020202020202020202020200a4172746973743a09095465737420617274697374202020202020202020202020202020202020200a43443a0909095465737420434420202020202020202020202020202020202020202020200a4c6162656c3a0954657374204c626c202000'
>>> crc32_func = crcmod.predefined.mkCrcFun('crc-32-mpeg')
>>> print hex(crc32_func(s))

The above code used payload example 4. As you can see the calculated checksum (0x14039bc3) does not match the original checksum that came with the payload (0x44d90b1d).

asked on Stack Overflow Oct 7, 2015 by Saja • edited Oct 9, 2015 by Saja

3 Answers


I can verify all your original CRCs with my Pascal Rocksoft implementation and the CRC-32/MPEG-2 from with these parameters


If in doubt about implementation, see the C source code included in the Rocksoft document. You find a Python implementation at (although I did not test this).

It seems clear (from your own reveng answer, from Marc's post, from my confirmation) that the given parameters are correct for your problem. But because you did show any code, the only suggestion I can give this that you should debug your code by comparing step-by-step with a proven C implementation.

answered on Stack Overflow Oct 9, 2015 by gammatester • edited Oct 9, 2015 by gammatester

So it turns out just passing the hex as a string doesn't end up with the right checksum via the python library crcmod. It won't take a bytearray either, which seemed to be a more probable way of calculating an accurate checksum. What you need to do is pass the bytearray as a buffer, and then the correct checksum is calculated.

Using the example in the question:

>>> import crcmod.predefined
>>> s = 'd3b09900004300005469746c653a090954657374207469746c652034202020202020202020202020202020202020202020202020202020200a4172746973743a09095465737420617274697374202020202020202020202020202020202020200a43443a0909095465737420434420202020202020202020202020202020202020202020200a4c6162656c3a0954657374204c626c202000'
>>> h = s.decode("hex")
>>> b = bytearray(h)
>>> crc32_func = crcmod.predefined.mkCrcFun('crc-32-mpeg')
>>> print hex(crc32_func(buffer(b)))

So there you have it. It was mostly just a lack of understanding of how CRC checksums are calculated I guess. Hope this ends up helping someone else.

answered on Stack Overflow Oct 16, 2015 by Saja

Here's how I calculate the crc for SCTE-35.

bites is just bytes.

 import crcmod.predefined

def mk_crc(bites):
    crc32_func = crcmod.predefined.mkCrcFun("crc-32-mpeg")
    crc_int = crc32_func(bites)
    crc = hex(crc_int)
answered on Stack Overflow Apr 29, 2021 by Leroy Scandal

User contributions licensed under CC BY-SA 3.0