-
-
Save oysstu/68072c44c02879a2abf94ef350d1c7c6 to your computer and use it in GitHub Desktop.
def crc16(data: bytes, poly=0x8408): | |
''' | |
CRC-16-CCITT Algorithm | |
''' | |
data = bytearray(data) | |
crc = 0xFFFF | |
for b in data: | |
cur_byte = 0xFF & b | |
for _ in range(0, 8): | |
if (crc & 0x0001) ^ (cur_byte & 0x0001): | |
crc = (crc >> 1) ^ poly | |
else: | |
crc >>= 1 | |
cur_byte >>= 1 | |
crc = (~crc & 0xFFFF) | |
crc = (crc << 8) | ((crc >> 8) & 0xFF) | |
return crc & 0xFFFF |
kjm1102
commented
Apr 27, 2023
via email
return('{:04X}'.format(crc))
Thanks, it works. Is there a better way to convert the list to be in a suitable format than this ChatGPT suggestion? (i'm very new to python)
bits_string = ''.join(str(bit) for bit in input_list)
int_value = int(bits_string, 2)
hex_value = hex(int_value)
hex_string = hex_value.replace('0x', '0x0') if len(hex_value) % 2 == 1 else hex_value
hex_value = bytes.fromhex(hex_string[2:])
crc=crc16(hex_value)
@pragma31 if I have a payload like this : " 623e0200000000000000000000000000" where 623e is crc given by a software i want to verify it , so what should i pass to get this value to the function that you have written here crc16 , thanks
same if i want to use https://crccalc.com/
@oysstu could you please guide me how could I use this code.
My data is (hex) E3BCBEBEA65EB3B87266124B2B238B6B
Polynomial is 0x1021
@oysstu This line is incorrect::
6 crc = 0xFFFF
This is incorrect because your code implements a bit-serial LFSR CRC calculator, but the INIT value of 0xFFFF comes from Ross Williams' Rocksoft^tm model, which is based on a table-driven calculation.
The Rocksoft model is described in Williams' crc_v3.txt, which you can find here
In the Rocksoft model, the initial value (0xFFFF) is loaded into the register, and the current contents of the register are XOR'd with the next incoming data bytes at the start of each iteration. You can see this in Williams' sample C code. Line 1635 in crc_v3.txt shows the INIT value being loaded into the register (p_cm->cm_reg), and line 1649 shows the data bytes being XOR'd into p_cm->cm_reg.
By preloading a serial LFSR with 0xFFFF, you're effectively prepending 0xFFFF to your block of data, which doesn't give the same result. What you actually want to do is XOR 0xFFFF with the first two bytes of data.
I recommend testing your algorithm against the calculator at sunshine2k.de. It gives correct results.