代码之家  ›  专栏  ›  技术社区  ›  AlexV

如何对python中的原始二进制数据使用位运算符进行CRC检查?

  •  2
  • AlexV  · 技术社区  · 6 年前

    这是我第一次在python中使用bitewise操作符和原始二进制数据,我正努力按照文档中的定义编写CRC检查代码。

    文档定义了CRC检入伪代码,如下所示:

    GENERATOR = 1111111111111010000001001
    
    MSG = binary("8D4840D6202CC371C32CE0576098")  # total 112 bits
    
    FOR i FROM 0 TO 88:                           # 112 - 24 parity bits
      if MSG[i] is 1:
        MSG[i:i+24] = MSG[i:i+24] ^ GENERATOR
    
    CRC = MSG[-24:]                               # last 24 bits
    
    IF CRC not 0:
      MSG is corrupted
    

    到目前为止,我已经对其进行了编码:

    adsb_hex = "8D4840D6202CC371C32CE0576098"
    adsb_dec = int(adsb_hex, 16)
    adsb_bin = bin(adsb_dec)[2:].zfill(8)
    
    generator = 0b1111111111111010000001001
    
    adsb_bin_list = [int((adsb_dec >> bit) & 1) for bit in range(112 - 1, -1, -1)]
    
    check = []
    for i in range(88):
        curr_bit = adsb_bin_list[i]
        if curr_bit is 1:
            check[i:i+24] = int(adsb_bin_list[i:i+24]) ^ generator
    
    crc = check[-24:]
    

    我不知道正确的方法是什么:

    MSG[i:i+24] = MSG[i:i+24] ^ GENERATOR
    
    CRC = MSG[-24:]
    

    我该怎么做才对呢,这是蟒蛇式的?

    2 回复  |  直到 6 年前
        1
  •  1
  •   WorldSEnder    6 年前

    如果您可以使用库,我建议您搜索您最喜欢的位串/位向量库。例如,使用 BitVector==3.4.8 你可以写

    from BitVector import BitVector
    
    generator = BitVector(bitstring='1111111111111010000001001')
    crc_length = len(generator) - 1
    
    def compute_crc(message : BitVector) -> BitVector:
        content_length = len(message) - crc_length
        # to encode a message, you pad it with 0
        # to decode, you pass in the message with the crc appended
        assert content_length >= 0
        # operate on a copy of the data
        message = message.deep_copy()
        for i in range(content_length):
            if message[i]:
                message[i:i + len(generator)] ^= generator
        return message[-crc_length:]
    
    if __name__ == "__main__":
        adsb_hex = "8D4840D6202CC371C32CE0576098"
        adsb_crc = compute_crc(BitVector(hexstring = adsb_hex))
    
        2
  •  0
  •   Dillon Davis    6 年前

    这里有一个更像蟒蛇的方法,你可以采取,虽然它放弃了直接位算术。

    msg_hex = "8D4840D6202CC371C32CE0576098"
    msg_dec = int(msg_hex, 16)
    msg_bin = list(bin(msg_dec)[2:].zfill(8))
    
    generator = "1111111111111010000001001"
    
    for i in range(88):
        if msg_bin[i] == "1":
            msg_bin[i:i+24] = ["1" if a != b else "0" for a, b in zip(msg_bin[i:i+24], generator)]
    
    if int("".join(msg_bin[-24:])):
        print("corrupted")
    

    你可以替换 "1" if a != b else "0" 具有 "01"[a!=b] 如果你愿意,但我认为前者更像是蟒蛇。

    我无法验证这个解决方案是否正确,因为您的代码没有编译,并且没有提到给定的生成器和消息应该产生什么。不过,我确实怀疑问题语句中存在错误,因为它正在检查最后24位,但生成器包含25位。