【问题标题】:Why does my conversion of four bytes to binary have only 30 binary digits?为什么我将四个字节转换为二进制只有 30 个二进制数字?
【发布时间】:2019-04-14 06:01:46
【问题描述】:

我有一个字符串形式的 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'

【问题讨论】:

  • 你问如何正确地做“那个”。你能描述一下“那个”到底是什么吗?在英语中,这段代码的目标是什么?周围的用例是什么?你能给出示例输入和预期输出吗?
  • @JohnZwinck 编辑澄清了吗?
  • 您知道 IPv4 地址是 4 个字节吗?为什么还要对它进行哈希处理然后取前 4 个字节?您可以直接使用二进制值。
  • @JohnZwinck 公平地说,这里的想法可能是为了记录目的匿名 IP 地址(获取二进制表示可能是为了测试匿名方案是否足够“随机”)。

标签: python python-3.x binary byte bit


【解决方案1】:

猜猜这会做的工作

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

【讨论】:

    【解决方案2】:

    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
    

    它有 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'
    

    【讨论】:

      猜你喜欢
      • 2017-11-22
      • 2013-03-06
      • 2021-02-24
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多