Chuyển đổi chuỗi thành nhị phân trong python


106

Tôi đang cần một cách để lấy biểu diễn nhị phân của một chuỗi trong python. ví dụ

st = "hello world"
toBinary(st)

Có một mô-đun của một số cách làm việc này gọn gàng không?


8
Cụ thể, bạn mong đợi kết quả đầu ra là gì?
NPE

Theo "nhị phân", bạn có nghĩa là loại 0101010 hay ordsố thứ tự của mỗi ký tự trong (ví dụ: hex)?
cdarke

Giả sử rằng bạn thực sự muốn nói là nhị phân (số không và số một), bạn có muốn biểu diễn nhị phân của từng ký tự (8 bit trên mỗi ký tự) một không? ví dụ: h là ascii giá trị 104 sẽ là 01101000 trong hệ nhị phân
ChrisProsser 15/09/13

Câu hỏi này đã được trả lời nhiều lần trên stackoverflow: stackoverflow.com/questions/11599226/… stackoverflow.com/questions/8553310/…
0xcaff, 15/09/13

Câu trả lời:


124

Một cái gì đó như thế này?

>>> 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
Hoặc nếu bạn muốn mỗi số nhị phân là 1 byte: '' .join (định dạng (ord (i), 'b') zfill (8) for i in st.)
ChrisProsser

5
Đối với các byte đầy đủ, bạn cũng có thể sử dụng ' '.join('{0:08b}'.format(ord(x), 'b') for x in st), nhanh hơn khoảng 35% so với zfill(8)giải pháp (ít nhất là trên máy của tôi).
tối đa

Còn về việc chuyển đổi các ký tự nhiều hơn một byte β, chẳng hạn như, đối với tôi, dường như được đại diện bởi 11001110 10110010nội bộ?
Sergey Bushmanov

1
Tôi biết điều này đã được đăng từ lâu, nhưng những gì về các ký tự không phải ASCII?
pkqxdd

48

Như một cách khó hiểu hơn, trước tiên bạn có thể chuyển đổi chuỗi của mình thành mảng byte sau đó sử dụng binhàm trong map:

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

Hoặc bạn có thể tham gia:

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

Lưu ý rằng trong python3, bạn cần chỉ định mã hóa cho bytearrayhàm:

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

Bạn cũng có thể sử dụng binasciimô-đun trong python 2:

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

hexlify trả về biểu diễn thập lục phân của dữ liệu nhị phân, sau đó bạn có thể chuyển đổi thành int bằng cách chỉ định 16 làm cơ sở của nó, sau đó chuyển nó thành nhị phân với bin .


5
Điều này không chỉ phức tạp hơn mà còn đúng hơn đối với các chuỗi không phải ASCII nhiều byte.
Sergey Bushmanov

Chỉ cần lưu ý rằng (ít nhất là đối với phiên bản hiện tại 3.7.4): (1) bytearraymong đợi một mã hóa (không chỉ là một chuỗi) và (2) map(bin, ...)sẽ trả về mapđối tượng. Về điểm đầu tiên, tôi sử dụng ví dụ bob.encoding ('ascii') 'theo đề xuất của @Tao. Đối với điều thứ hai, hãy sử dụng joinphương thức, như trong các ví dụ khác của @Kasramvd sẽ hiển thị kết quả mong muốn.
Antoine

35

Chúng ta chỉ cần mã hóa nó.

'string'.encode('ascii')

Đối với tôi ( v3.7.4), điều này trả về một bytesđối tượng (với các biểu diễn ascii của mỗi byte, nếu có) và để hiển thị biểu diễn nhị phân của nó, tôi cần bin, ví dụ: với ' '.join(item[2:] for item in map(bin, 'bob'.encode('ascii')))(lưu ý rằng 0bcần được xóa ở đầu biểu diễn nhị phân của mỗi nhân vật).
Antoine

15

Bạn có thể truy cập các giá trị mã cho các ký tự trong chuỗi của mình bằng cách sử dụng ord()hàm tích hợp. Nếu sau đó bạn cần định dạng nó ở dạng nhị phân, string.format()phương thức sẽ thực hiện công việc.

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

(Cảm ơn Ashwini Chaudhary đã đăng đoạn mã đó.)

Mặc dù mã trên hoạt động trong Python 3, nhưng vấn đề này sẽ phức tạp hơn nếu bạn giả sử bất kỳ mã hóa nào khác ngoài UTF-8. Trong Python 2, chuỗi là chuỗi byte và mã hóa ASCII được giả định theo mặc định. Trong Python 3, các chuỗi được giả định là Unicode và có mộtbytes loại hoạt động giống chuỗi Python 2 hơn. Nếu bạn muốn giả sử bất kỳ mã hóa nào khác ngoài UTF-8, bạn sẽ cần chỉ định mã hóa.

Trong Python 3, sau đó, bạn có thể làm như sau:

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

Sự khác biệt giữa mã hóa UTF-8 và ascii sẽ không rõ ràng đối với các chuỗi chữ và số đơn giản, nhưng sẽ trở nên quan trọng nếu bạn đang xử lý văn bản bao gồm các ký tự không có trong bộ ký tự ascii.


2

Trong phiên bản Python 3.6 trở lên, bạn có thể sử dụng f-string để định dạng kết quả.

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

01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100
  • Phía bên trái của dấu hai chấm, ord (i), là đối tượng thực tế có giá trị sẽ được định dạng và chèn vào đầu ra. Sử dụng ord () cung cấp cho bạn điểm mã cơ sở 10 cho một ký tự str.

  • Phía bên phải của dấu hai chấm là ký hiệu định dạng. 08 có nghĩa là chiều rộng 8, 0 được đệm và b có chức năng như một dấu hiệu để xuất ra số kết quả trong cơ số 2 (nhị phân).


1

Đây là bản cập nhật cho các câu trả lời hiện có đã được sử dụng bytearray()và không thể hoạt động theo cách đó nữa:

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

Bởi vì, như đã giải thích trong liên kết ở trên, nếu nguồn là một chuỗi, bạn cũng phải cung cấp mã hóa :

>>> 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 về cơ bản hiệu quả hơn trong việc chuyển đổi thành mảng byte vì nó thực hiện các lệnh gọi hàm mức thấp thay vì chuyển đổi thủ công mọi ký tự thành số nguyên, sau đó chuyển đổi số nguyên đó thành giá trị nhị phân của nó.


-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
Bạn có muốn bổ sung câu trả lời chỉ có mã khó đọc này với một số giải thích không? Điều đó sẽ giúp chống lại quan niệm sai lầm rằng StackOverflow là một dịch vụ viết mã miễn phí. Trong trường hợp bạn muốn cải thiện khả năng đọc, hãy thử các thông tin cung cấp ở đây: stackoverflow.com/editing-help
Yunnosch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.