繁体   English   中英

如何在二进制整数(python)中保留前导零?

[英]How to keep leading zeros in binary integer (python)?

我需要使用 XOR 计算十六进制串行字串的校验和。 据我(有限)所知,这必须使用按位运算符 ^ 来执行。 此外,数据必须转换为二进制整数形式。 下面是我的基本代码 - 但它计算的校验和是 1000831。它应该是 01001110 或 47hex。 我认为错误可能是由于缺少前导零。 我尝试添加前导零的所有格式都将二进制整数转回字符串。 我很感激任何建议。

    word = ('010900004f')

    #divide word into 5 separate bytes
    wd1 = word[0:2] 
    wd2 = word[2:4]
    wd3 = word[4:6]
    wd4 = word[6:8]
    wd5 = word[8:10]

    #this converts a hex string to a binary string
    wd1bs = bin(int(wd1, 16))[2:] 
    wd2bs = bin(int(wd2, 16))[2:]
    wd3bs = bin(int(wd3, 16))[2:]
    wd4bs = bin(int(wd4, 16))[2:]

    #this converts binary string to binary integer
    wd1i = int(wd1bs)
    wd2i = int(wd2bs)
    wd3i = int(wd3bs)
    wd4i = int(wd4bs)
    wd5i = int(wd5bs)

    #now that I have binary integers, I can use the XOR bitwise operator to cal cksum
    checksum = (wd1i ^ wd2i ^ wd3i ^ wd4i ^ wd5i)

    #I should get 47 hex as the checksum
    print (checksum, type(checksum))

为什么要使用所有这些转换和昂贵的字符串函数?

(我会回答你的XY-Problem的 X 部分,而不是 Y 部分。)

def checksum (s):
    v = int (s, 16)
    checksum = 0
    while v:
        checksum ^= v & 0xff
        v >>= 8
    return checksum

cs = checksum ('010900004f')
print (cs, bin (cs), hex (cs) )

结果是预期的 0x47。 顺便说一句,0x47 是 0b1000111 而不是 0b1001110。

就这样修改。

前:

wd1i = int(wd1bs)
wd2i = int(wd2bs)
wd3i = int(wd3bs)
wd4i = int(wd4bs)
wd5i = int(wd5bs)

后:

wd1i = int(wd1bs, 2)
wd2i = int(wd2bs, 2)
wd3i = int(wd3bs, 2)
wd4i = int(wd4bs, 2)
wd5i = int(wd5bs, 2)

为什么你的代码不起作用?

因为您误解了int(wd1bs)行为。 请参阅此处的文档。 所以 Python int函数期望wd1bs默认为 10 基数。 但是您希望int函数将其参数视为 2 基数。 所以你需要写成int(wd1bs, 2)


或者您也可以像这样重写整个代码。 所以在这种情况下你不需要使用bin函数。 并且此代码与@Hyperboreus 的答案基本相同。 :)

w = int('010900004f', 16)
w1 = (0xff00000000 & w) >> 4*8
w2 = (0x00ff000000 & w) >> 3*8
w3 = (0x0000ff0000 & w) >> 2*8
w4 = (0x000000ff00 & w) >> 1*8
w5 = (0x00000000ff & w)

checksum = w1 ^ w2 ^ w3 ^ w4 ^ w5

print hex(checksum)
#'0x47'

这是更短的一个。

import binascii
word = '010900004f'
print hex(reduce(lambda a, b: a ^ b, (ord(i) for i in binascii.unhexlify(word))))
#0x47
s = '010900004f'
b = int(s, 16)
print reduce(lambda x, y: x ^ y, ((b>> 8*i)&0xff for i in range(0, len(s)/2)), 0)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM