Конвертировать шестнадцатеричный код в двоичный - PullRequest
84 голосов
/ 15 сентября 2009

У меня есть ABC123EFFF.

Я хочу иметь 001010101111000001001000111110111111111111 (то есть двоичный отчет, скажем, с 42 цифрами и ведущими нулями).

Как?

Ответы [ 18 ]

93 голосов
/ 01 февраля 2011

Для решения задачи с левым концевым нулем:


my_hexdata = "1a"

scale = 16 ## equals to hexadecimal

num_of_bits = 8

bin(int(my_hexdata, scale))[2:].zfill(num_of_bits)

Это даст 00011010 вместо усеченной версии.

51 голосов
/ 15 сентября 2009
import binascii

binary_string = binascii.unhexlify(hex_string)

Читать

binascii.unhexlify

Возвращает двоичные данные, представленные шестнадцатеричной строкой, указанной в качестве параметра.

40 голосов
/ 15 сентября 2009
bin(int("abc123efff", 16))[2:]
29 голосов
/ 29 июля 2014
>>> bin( 0xABC123EFFF )

'0b1010101111000001001000111110111111111111'

25 голосов
/ 14 мая 2016

Преобразование шестнадцатеричного значения в двоичное

У меня есть ABC123EFFF.

Я хочу иметь 001010101111000001001000111110111111111111 (т.е. двоичный файл магнезии. скажем, с 42 цифрами и ведущими нулями).

Краткий ответ:

Новые f-строки в Python 3.6 позволяют вам делать это, используя очень краткий синтаксис:

>>> f'{0xABC123EFFF:0>42b}'
'001010101111000001001000111110111111111111'

или разбить его на семантику:

>>> number, pad, rjust, size, kind = 0xABC123EFFF, '0', '>', 42, 'b'
>>> f'{number:{pad}{rjust}{size}{kind}}'
'001010101111000001001000111110111111111111'

Длинный ответ:

Что вы на самом деле говорите, так это то, что у вас есть значение в шестнадцатеричном представлении, и вы хотите представить эквивалентное значение в двоичном виде.

Значение эквивалентности является целым числом. Но вы можете начать со строки, а для просмотра в двоичном виде вы должны закончить строкой.

Преобразовать шестнадцатеричный код в двоичный, 42 цифры и начальные нули?

У нас есть несколько прямых способов достичь этой цели, без взлома с использованием ломтиков.

Во-первых, прежде чем мы вообще сможем выполнять какие-либо двоичные манипуляции, преобразуем в int (я предполагаю, что это строковый формат, а не литерал):

>>> integer = int('ABC123EFFF', 16)
>>> integer
737679765503

в качестве альтернативы мы могли бы использовать целочисленный литерал в шестнадцатеричной форме:

>>> integer = 0xABC123EFFF
>>> integer
737679765503

Теперь нам нужно выразить наше целое число в двоичном представлении.

Используйте встроенную функцию, format

Затем перейдите к format:

>>> format(integer, '0>42b')
'001010101111000001001000111110111111111111'

При этом используется спецификация форматирования мини-язык .

Чтобы разбить это, вот грамматическая форма этого:

[[fill]align][sign][#][0][width][,][.precision][type]

Чтобы сделать это спецификацией для наших нужд, мы просто исключаем то, что нам не нужно:

>>> spec = '{fill}{align}{width}{type}'.format(fill='0', align='>', width=42, type='b')
>>> spec
'0>42b'

и просто передайте это в формат

>>> bin_representation = format(integer, spec)
>>> bin_representation
'001010101111000001001000111110111111111111'
>>> print(bin_representation)
001010101111000001001000111110111111111111

Форматирование строк (шаблонов) с str.format

Мы можем использовать это в строке, используя str.format метод:

>>> 'here is the binary form: {0:{spec}}'.format(integer, spec=spec)
'here is the binary form: 001010101111000001001000111110111111111111'

Или просто поместите спецификацию прямо в исходную строку:

>>> 'here is the binary form: {0:0>42b}'.format(integer)
'here is the binary form: 001010101111000001001000111110111111111111'

Форматирование строк с новыми f-строками

Давайте продемонстрируем новые f-строки. Они используют одни и те же правила форматирования мини-языка:

>>> integer = 0xABC123EFFF
>>> length = 42
>>> f'{integer:0>{length}b}'
'001010101111000001001000111110111111111111'

Теперь давайте добавим эту функцию в функцию, которая будет стимулировать повторное использование:

def bin_format(integer, length):
    return f'{integer:0>{length}b}'

А теперь:

>>> bin_format(0xABC123EFFF, 42)
'001010101111000001001000111110111111111111'    

Помимо

Если вы на самом деле просто хотели закодировать данные в виде строки байтов в памяти или на диске, вы можете использовать метод int.to_bytes, который доступен только в Python 3:

>>> help(int.to_bytes)
to_bytes(...)
    int.to_bytes(length, byteorder, *, signed=False) -> bytes
...

А так как 42 бита, разделенные на 8 бит на байт, равны 6 байтов:

>>> integer.to_bytes(6, 'big')
b'\x00\xab\xc1#\xef\xff'
14 голосов
/ 28 февраля 2012
"{0:020b}".format(int('ABC123EFFF', 16))
9 голосов
/ 15 сентября 2009

Вот довольно грубый способ сделать это, используя битовое кодирование для генерации двоичных строк.

Ключ, который нужно понять:

(n & (1 << i)) and 1

Который будет генерировать 0 или 1, если установлен i-й бит n.


import binascii

def byte_to_binary(n):
    return ''.join(str((n & (1 << i)) and 1) for i in reversed(range(8)))

def hex_to_binary(h):
    return ''.join(byte_to_binary(ord(b)) for b in binascii.unhexlify(h))

print hex_to_binary('abc123efff')

>>> 1010101111000001001000111110111111111111

Редактировать: используя "новый" троичный оператор, это:

(n & (1 << i)) and 1

станет:

1 if n & (1 << i) or 0

(Какой TBH я не уверен, насколько это читабельно)

5 голосов
/ 10 сентября 2011

Это небольшое исправление решения Глена Мейнарда, которое, я думаю, является правильным способом сделать это. Он просто добавляет элемент заполнения.


    def hextobin(self, hexval):
        '''
        Takes a string representation of hex data with
        arbitrary length and converts to string representation
        of binary.  Includes padding 0s
        '''
        thelen = len(hexval)*4
        binval = bin(int(hexval, 16))[2:]
        while ((len(binval)) &lt thelen):
            binval = '0' + binval
        return binval

Вытащил это из класса. Просто уберите self, , если вы работаете в автономном скрипте.

4 голосов
/ 20 февраля 2017
bin(int("abc123efff", 16))[2:]

'1010101111000001001000111110111111111111'

`bin(int("abc123efff", 16))[2:].zfill(50)`

'00000000001010101111000001001000111110111111111111'

(Число 50 сообщит zfill, что вы хотите дополнить строку нулями, пока длина строки не станет 50.)

3 голосов
/ 15 сентября 2009

Заменить каждую шестнадцатеричную цифру соответствующими 4 двоичными цифрами:

1 - 0001
2 - 0010
...
a - 1010
b - 1011
...
f - 1111
...