Почему мое преобразование четырех байтов в двоичное имеет только 30 двоичных цифр? - PullRequest
0 голосов
/ 11 ноября 2018

У меня есть 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'. Я попробовал методы здесь, и ни один не работает с форматом, из которого я преобразовываю. Преобразование байтов в биты в питоне

  • Что у меня есть: 4 байта из хэша 32-битной строки IP-адреса, то есть: b',\xc3Z\xfb'
  • Что я пытаюсь получить: двоичное представление 32 в виде строки, то есть: '10101010101010101010101010101010'

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

bin() дает двоичное представление целого числа. Конкретное целое число, которое вы запрашиваете в двоичном представлении, в этом случае является результатом struct.unpack('!I', b',\xc3Z\xfb')[0], который равен 751000315:

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

Двоичное представление 751000315, которое дает bin(), равно 0b101100110000110101101011111011, что правильно:

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

У него тридцать цифр (плюс префикс 0b), потому что именно столько цифр необходимо для представления этого целого числа. если бы результатом struct.unpack('!I', H(R))[0] было, скажем, целое число 38 (например, если бы R было '247.69.16.15'), двоичное представление bin() дало бы вам 0b100110, что еще короче.

bin() не могу догадаться, что вам нужны ведущие нули, и он, конечно, не может угадать, сколько. Что вам нужно сделать, это формат ваше целое число, например:

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

… или, в крайнем примере, который я привел выше:

>>> '{:032b}'.format(struct.unpack('!I', H('247.69.16.15'))[0])
'00000000000000000000000000100110'
0 голосов
/ 11 ноября 2018

Думаю, это сработает

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
...