为什么我将四个字节转换为二进制只有 30 个二进制数字?

Why does my conversion of four bytes to binary have only 30 binary digits?

我有一个字符串形式的 IP 地址 R(即:"255.255.255.0"),我正在对其进行哈希处理,并获取该哈希的前 4 个字节。然后我想将该散列结果转换为二进制格式:

def H(R):
    h = hashlib.sha256(R.encode('utf-8'))
    return unhexlify(h.hexdigest())[0:4]

我尝试执行以下操作,但我只得到 30 位而不是 32 位(我删除了字符串的前 2 个字符,因为它是 0b 前缀):

bin(struct.unpack('!I', H(R))[0])[2:]

我怎样才能正确地做到这一点? H(R) 的结果类似于 b',\xc3Z\xfb'。我已经尝试了这里的方法并且 none 使用我正在转换的格式。 Convert bytes to bits in python

猜猜这会起作用

import hashlib
import binascii

def H(R):
    h = hashlib.sha256(R.encode('utf-8'))
    return binascii.unhexlify(h.hexdigest())[0:4]

def binstr(x: bytes) -> str:
    s = ""
    for char in x:
        ch = bin(char)[2:] # 0b101 -> 101
        s += "0" * (8-len(ch)) + ch # 101 -> 00000101
    return s

print(binstr(H("127.0.0.1"))) # 00010010110010100001011110110100
print(binstr(H("255.255.255.255"))) # 11110100010101000110001010111111

bin() 给你一个整数的二进制表示。在这种情况下,您要求二进制表示的特定整数是 struct.unpack('!I', b',\xc3Z\xfb')[0] 的结果,它恰好是 751000315:

>>> struct.unpack('!I', b',\xc3Z\xfb')[0]
751000315

bin()给你的751000315的二进制表示是0b101100110000110101101011111011,正确的是:

>>> bin(751000315)
'0b101100110000110101101011111011'
>>> 0b101100110000110101101011111011
751000315

它有三十位数字(加上 0b 前缀),因为这是表示该整数所必需的位数。例如,如果 struct.unpack('!I', H(R))[0] 的结果是整数 38(例如,如果 R'247.69.16.15'),则二进制表示 bin() 会是 0b100110,甚至更短。

bin() 猜不出你想要前导零,当然也猜不出有多少。你需要做的是format你的整数,像这样:

>>> '{:032b}'.format(struct.unpack('!I', b',\xc3Z\xfb')[0])
'00101100110000110101101011111011'

... 或者,在我上面给出的极端示例中:

>>> '{:032b}'.format(struct.unpack('!I', H('247.69.16.15'))[0])
'00000000000000000000000000100110'