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!
Edit:
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))
0x14039bc3
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).
I can verify all your original CRCs with my Pascal Rocksoft implementation and the CRC-32/MPEG-2 from http://reveng.sourceforge.net/crc-catalogue/ with these parameters
width=32
poly=0x04c11db7
init=0xffffffff
refin=false
refout=false
xorout=0x00000000
check=0x0376e6e7
name="CRC-32/MPEG-2"
If in doubt about implementation, see the C source code included in the Rocksoft document. You find a Python implementation at https://pycrc.org/models.html (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.
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)))
0x44d90b1d
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.
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)
User contributions licensed under CC BY-SA 3.0