Перетворити рядок у двійковий у python


106

Мені потрібен спосіб отримати двійкове представлення рядка в python. напр

st = "hello world"
toBinary(st)

Чи є модуль якогось акуратного способу зробити це?


8
Яким ви очікуєте конкретно результатом?
NPE

Під "двійковим" ви маєте на увазі тип 0101010 або внутрішній ordномер кожного символу (наприклад, шестигранник)?
cdarke

Якщо припустити, що ви насправді маєте на увазі двійкові (нулі та одиниці), чи хочете ви двійкове представлення кожного символу (8 біт на символ) один за одним? наприклад, h - значення ascii 104, було б 01101000 у двійковій
формі

Це питання було дано відповіді багато разів на StackOverflow: stackoverflow.com/questions/11599226 / ... stackoverflow.com/questions/8553310 / ...
0xcaff

можливий дублікат Convert Binary в ASCII і навпаки (Python)
jfs

Відповіді:


124

Щось на зразок цього?

>>> st = "hello world"
>>> ' '.join(format(ord(x), 'b') for x in st)
'1101000 1100101 1101100 1101100 1101111 100000 1110111 1101111 1110010 1101100 1100100'

#using `bytearray`
>>> ' '.join(format(x, 'b') for x in bytearray(st, 'utf-8'))
'1101000 1100101 1101100 1101100 1101111 100000 1110111 1101111 1110010 1101100 1100100'

21
Або якщо ви хочете, щоб кожне двійкове число було 1 байт: '' .join (формат (ord (i), 'b'). Zfill (8) для i in st)
ChrisProsser

5
Для повних байтів ви також можете використовувати ' '.join('{0:08b}'.format(ord(x), 'b') for x in st), що приблизно на 35% швидше, ніж zfill(8)рішення (принаймні, на моїй машині).
макс

А як щодо перетворення символів, що більше одного байта, як β, наприклад, який, як мені здається, представлений 11001110 10110010внутрішньо?
Сергій Бушманов

1
Я знаю, що це було розміщено давно, але як бути з символами, що не належать до ASCII?
pkqxdd

48

Як більш пітонічний спосіб, ви можете спочатку перетворити рядок у байтовий масив, а потім використовувати binфункцію в межах map:

>>> st = "hello world"
>>> map(bin,bytearray(st))
['0b1101000', '0b1100101', '0b1101100', '0b1101100', '0b1101111', '0b100000', '0b1110111', '0b1101111', '0b1110010', '0b1101100', '0b1100100']

Або ви можете приєднатися до нього:

>>> ' '.join(map(bin,bytearray(st)))
'0b1101000 0b1100101 0b1101100 0b1101100 0b1101111 0b100000 0b1110111 0b1101111 0b1110010 0b1101100 0b1100100'

Зауважте, що в python3 потрібно вказати кодування для bytearrayфункції:

>>> ' '.join(map(bin,bytearray(st,'utf8')))
'0b1101000 0b1100101 0b1101100 0b1101100 0b1101111 0b100000 0b1110111 0b1101111 0b1110010 0b1101100 0b1100100'

Ви також можете використовувати binasciiмодуль у python 2:

>>> import binascii
>>> bin(int(binascii.hexlify(st),16))
'0b110100001100101011011000110110001101111001000000111011101101111011100100110110001100100'

hexlifyповернути шістнадцяткове представлення бінарних даних, тоді ви можете перетворити в int, вказавши 16 як його базу, а потім перетворити їх у двійкові bin.


5
Це не тільки пітонічно, але це "більш" правильно для багатобайтових рядків, що не належать до ASCII.
Сергій Бушманов

Зауважимо лише, що (принаймні для поточної версії 3.7.4): (1) bytearrayочікує, що кодування (а не лише рядок) і (2) map(bin, ...)повернуть mapоб'єкт. Для першого пункту я використовую, наприклад, bob.encoding ('ascii') `, як запропонував @Tao. По-друге, вкажіть, використовуючи joinметод, як в інших прикладах @Kasramvd відобразить бажаний результат.
Антуан

35

Нам просто потрібно його кодувати.

'string'.encode('ascii')

Для мене ( v3.7.4) це повертає bytesоб'єкт (з представленнями ascii кожного байту, якщо він є), і для того, щоб відобразити його бінарне представлення, мені потрібно bin, наприклад, з ' '.join(item[2:] for item in map(bin, 'bob'.encode('ascii')))(зверніть увагу, що 0bйого потрібно видалити на початку бінарного представлення кожного персонажа).
Антуан

15

Ви можете отримати доступ до значень коду для символів у рядку за допомогою ord()вбудованої функції. Якщо вам потрібно буде відформатувати це у двійковому форматі, string.format()метод зробить цю роботу.

a = "test"
print(' '.join(format(ord(x), 'b') for x in a))

(Дякую Ешвіні Шадхарі за публікацію фрагмента коду.)

Хоча вищезазначений код працює в Python 3, це питання ускладнюється, якщо ви припускаєте будь-яке кодування, крім UTF-8. У Python 2 рядки є послідовностями байтів, а кодування ASCII передбачається за замовчуванням. У Python 3 рядки вважаються Unicode, і існує окремий bytesтип, який більше схожий на рядок Python 2. Якщо ви хочете припустити будь-яке кодування, крім UTF-8, вам потрібно буде вказати кодування.

У Python 3 ви можете зробити щось подібне:

a = "test"
a_bytes = bytes(a, "ascii")
print(' '.join(["{0:b}".format(x) for x in a_bytes]))

Відмінності між кодуванням UTF-8 та кодуванням ascii не будуть очевидними для простих буквено-цифрових рядків, але стануть важливими, якщо ви обробляєте текст, який включає символи, що не містяться в наборі символів ascii.


2

У версії Python 3.6 і вище ви можете використовувати f-string для форматування результату.

str = "hello world"
print(" ".join(f"{ord(i):08b}" for i in str))

01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100
  • Ліва сторона двокрапки, ord (i), є фактичним об'єктом, значення якого буде відформатоване та вставлено у висновок. Використання ord () дає точку коду базового 10 для одного символу str.

  • Права частина двокрапки - специфікатор формату. 08 означає ширину 8, 0 прокладений, а b функціонує як знак для виведення отриманого числа в базі 2 (двійкові).


1

Це оновлення для існуючих відповідей, які використовувались bytearray()і більше не можуть працювати таким чином:

>>> st = "hello world"
>>> map(bin, bytearray(st))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding

Тому що, як пояснено у посиланні вище, якщо джерелом є рядок, ви також повинні дати кодування :

>>> map(bin, bytearray(st, encoding='utf-8'))
<map object at 0x7f14dfb1ff28>

0
def method_a(sample_string):
    binary = ' '.join(format(ord(x), 'b') for x in sample_string)

def method_b(sample_string):
    binary = ' '.join(map(bin,bytearray(sample_string,encoding='utf-8')))


if __name__ == '__main__':

    from timeit import timeit

    sample_string = 'Convert this ascii strong to binary.'

    print(
        timeit(f'method_a("{sample_string}")',setup='from __main__ import method_a'),
        timeit(f'method_b("{sample_string}")',setup='from __main__ import method_b')
    )

# 9.564299999998184 2.943955828988692

method_b є значно ефективнішим при перетворенні в байтовий масив, оскільки він робить виклики функцій низького рівня, а не вручну перетворює кожен символ у ціле число, а потім перетворює це ціле число у його бінарне значення.


-1
a = list(input("Enter a string\t: "))
def fun(a):
    c =' '.join(['0'*(8-len(bin(ord(i))[2:]))+(bin(ord(i))[2:]) for i in a])
    return c
print(fun(a))

1
Чи хотіли б ви доповнити цю нечитабельну відповідь лише для коду деяким поясненням? Це допоможе боротися з помилковим уявленням про те, що StackOverflow - це послуга безкоштовного написання коду. У разі , якщо ви хочете , щоб поліпшити читаність, спробуйте Інформація , представлена тут: stackoverflow.com/editing-help
Yunnosch
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.