我需要计算从Iridium模块(短突发数据)接收的消息校验和的最低2字节(以字节为单位)。
我使用的代码在大多数情况下都适用,但不适用于下面的示例。
我的代码是:
z=b"AT+SBDRB\r\x00\x18this is a random message\x08\xdb"#message received from Iridium module
msg=z[11:-2]
print(msg)
checksum_received = z[-2:]
checksum = 0
check_it = False
for c in msg:
checksum = checksum + c #msg is a byte type
a=chr( checksum >> 8 )
b=chr( checksum & 0xFF )
c=a.encode()
d=b.encode()
checksum = c + d
print(c.hex())
print(d.hex())
print(checksum.hex())
print(checksum_received.hex())
print(checksum == checksum_received)
在上面的情况下,校验和与我收到的校验和不同(我试图多次发送消息以确保我确实没有收到传输错误)。
我已使用以下消息测试了代码,并且两个校验和是相同的:
z=b"AT+SBDRB\r\x00\x05hello\x02\x14"
z=b"AT+SBDRB\r\x00\x14thisisarandommessage\x08["
z=b"AT+SBDRB\r\x00\x15this isarandommessage\x08{"
铱星SBDS手册中提供的唯一信息是:
校验和是最小的2字节的总和 整个SBD消息。必须先发送高位字节。例如 如果FA将以ASCII编码的单词“hello”发送给ISU二进制文件 stream将是hex 68 65 6c 6c 6f 02 14。
答案 0 :(得分:0)
您似乎将计算的校验和转换为两个单独的chr()
值,然后对其进行编码。
更简单:
z=b"AT+SBDRB\r\x00\x18this is a random message\x08\xdb"#message received from Iridium module
msg=z[11:-2]
print(msg)
checksum_received = z[-2:]
# checksum = 0
# for c in msg:
# checksum = checksum + c #msg is a byte type
checksum = sum(msg)
# checksum is the correct value here
print(hex(checksum))
a = checksum >> 8
b = checksum & 0xFF
# Now convert checksum back into a bytes object just like z[-2:] above
checksum = bytes([a,b])
print(checksum.hex())
print(checksum_received.hex())
# now these two are the same
print(checksum == checksum_received)
答案 1 :(得分:0)
我研究了Virtenio在其Iridium Gateway上使用的代码,看来quamrana是正确的。我可以提供以下Java函数来计算校验和。 Java,因为Virtenio具有用于嵌入式系统的PreonVM,可以在JAVA中对其进行编程。这是代码:
int calcChecksum(byte[] data, int length) {
int checkSum = 0;
for (int i = 0; i < length; i++) {
checkSum += data[i] & 0xFF;
}
return checkSum & 0xFFFF;
}
然后,您必须将计算出的校验和与接收到的校验和进行比较,如果它们匹配,则接收到的数据是有效的。通过将数据的所有字节求和即可简单地计算出校验和。校验和是两个字节长,因此您只需要求和的低两个字节即可。