def crc16_ccitt_false(data: bytes) -> int:
"""CRC16/CCITT-FALSE 算法"""
crc = 0xFFFF
for i, b in enumerate(data):
crc ^= b << 8
print("After XOR with byte %d (0x%02X): 0x%04X"%(i, data[i], crc))
for j, _ in enumerate(range(8)):
if (crc & 0x8000):
crc = (crc << 1) ^ 0x1021
print("Bit %d set, after shift and XOR: 0x%04X"%(j, crc))
else:
crc = crc << 1
print("Bit %d not set, after shift: 0x%04X"%(j, crc))
crc &= 0xFFFF
print("Final CRC: 0x%04X"%crc)
return crc
def check_payload(payload: bytes):
print("len(payload): ", len(payload))
if not (126 <= len(payload) <= 472):
print("载荷长度不在126~472之间")
return False
print(payload[8:92])
crcValue = crc16_ccitt_false(payload[8:92])
print("crcValue: ", crcValue)
crcOffset = (crcValue % 200) + 92
print("crcOffset: ", crcOffset)
if crcOffset + 2 >= len(payload):
print("载荷长度不足92字节")
return False
data_crc = int.from_bytes(payload[crcOffset:crcOffset+2], byteorder='big')
print("data_crc: ", data_crc)
if data_crc != crcValue:
print("对比计算的CRC16值与载荷中记12录的CRC16值")
return False
if crcOffset + 3 > len(payload):
print("判断偏移过后3个字节是否超过TCP载荷长度")
return False
value_after_crc = int.from_bytes(payload[crcOffset+2:crcOffset+4], byteorder='big')
if value_after_crc % 127 != 0:
print("判断校验值是否为127的整数倍")
return False
trigger_start = crcOffset + 12
if trigger_start + 29 > len(payload):
print("判断是否超过TCP载荷长度")
return False
trigger_payload = payload[trigger_start:trigger_start+29]
xor_key_start = (crcValue % 55) + 8
if xor_key_start + 29 > len(payload):
print("判断是否超过TCP载荷长度")
return False
xor_key = payload[xor_key_start:xor_key_start+29]
result = bytes([a ^ b for a, b in zip(trigger_payload, xor_key)])
print(f"Decrypted Payload (hex): {result.hex()}")
if len(result) < 29:
print("len(result) < 29")
return False
return True
payload_hex = '029b01387011fe6939076f77c0bfda2c0267e7a5bc68c00ac5d82d3bfa5c13fcf71434672632d15f3a40d6fa00b02602180da7d47667de3b3f0b76396889365f9e6ac7c49d9823d7d8fad1d8aaf7dbc20582967bea74b629802c63e8b599475303697d6b283b777f354857df40f92a46bb41be617da9de84c5c4b63bf24d006841862aeba07805788aa712681ab4adcfec6d6e99e337c68562dbdd273888efa34a57b44837457a602d8cc8474076172de385c6c7bc8d4c1f682946a0b13543fc8cf844c43dbe246a4becb18b62c8b8464e7f0d0a0c592974836f1534a45830315074f58d3319f77e05a9096871c2aebf41bbca4d14f3c19763d6cc072ffc387f712d0da44604224cad2bb41fed62de2e1da87b319c3dc9ff13950642913fc2'
ret = check_payload(bytes.fromhex(payload_hex))
print(ret)