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

2024-06-28 15:17:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个字符串形式的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'。我在这里尝试过这些方法,但没有一种方法能与我正在转换的格式兼容。Convert bytes to bits in python

  • 我拥有的是:32位IP地址字符串哈希中的4个字节,即:b',\xc3Z\xfb'
  • 我想得到的是:32位二进制字符串,即:'10101010101010101010101010101010'

Tags: 方法字符串return字节def格式二进制形式
2条回答

^{}给出整数的二进制表示。在本例中,您要求二进制表示的特定整数是struct.unpack('!I', b',\xc3Z\xfb')[0]的结果,恰好是751000315:

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

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

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

它有30个数字(加上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'

我想这就行了

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

相关问题 更多 >