แปลงสตริงเป็นไบนารีใน python


109

ฉันต้องการวิธีรับการแสดงไบนารีของสตริงใน python เช่น

st = "hello world"
toBinary(st)

มีโมดูลวิธีการทำสิ่งนี้อย่างเรียบร้อยหรือไม่?


9
คุณคาดหวังว่าผลลัพธ์จะเป็นอย่างไรโดยเฉพาะ?
NPE

โดย "ไบนารี" คุณหมายถึงประเภท 0101010 หรือordจำนวน inal ของแต่ละอักขระใน (เช่นฐานสิบหก)?
cdarke

สมมติว่าคุณหมายถึงไบนารี (เลขศูนย์และตัว) คุณต้องการให้ตัวแทนไบนารีของแต่ละอักขระ (8 บิตต่ออักขระ) ทีละตัวหรือไม่? เช่น h คือค่า ascii 104 จะเป็น 01101000 ในไบนารี
ChrisProsser

คำถามนี้ได้รับการตอบหลายครั้งใน StackOverflow: stackoverflow.com/questions/11599226/... stackoverflow.com/questions/8553310/...
0xcaff

เป็นไปได้ที่จะทำซ้ำการแปลง Binary เป็น ASCII และในทางกลับกัน (Python)
jfs

คำตอบ:


127

อะไรทำนองนี้?

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

23
หรือถ้าคุณต้องการให้แต่ละเลขฐานสองเป็น 1 ไบต์: '' .join (format (ord (i), 'b'). zfill (8) for i in st)
ChrisProsser

5
สำหรับไบต์เต็มคุณสามารถใช้ได้' '.join('{0:08b}'.format(ord(x), 'b') for x in st)ซึ่งเร็วกว่าzfill(8)โซลูชันประมาณ 35% (อย่างน้อยก็ในเครื่องของฉัน)
สูงสุด

แล้วการแปลงตัวอักษรมากกว่าหนึ่งไบต์βเช่นซึ่งดูเหมือนว่าฉันจะแสดงโดย11001110 10110010ภายในล่ะ
Sergey Bushmanov

1
ฉันรู้ว่าสิ่งนี้โพสต์ไว้นานแล้ว แต่อักขระที่ไม่ใช่ ASCII ล่ะ
Jerie Wang

รูปแบบจำเพาะ Mini-ภาษา : ' '.join('{:08b}'.format(d) for d in bytearray('ß', 'utf-8'))เอาท์พุท: '11000011 10011111'ลองเข้ารหัสอื่น ๆutf-16, utf-32สำหรับไม่ใช่ ASCII
Kuo

49

ในฐานะที่เป็นวิธี pythonic คุณสามารถแปลงสตริงของคุณเป็นไบต์อาร์เรย์ก่อนจากนั้นใช้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เป็นฐานแล้วแปลงเป็นไบนารีด้วย


6
ไม่เพียง แต่เป็นไพโธนิกเท่านั้น แต่ยังถูกต้อง "มากกว่า" สำหรับสตริงที่ไม่ใช่ ASCII แบบหลายไบต์
Sergey Bushmanov

โปรดทราบว่า (อย่างน้อยสำหรับเวอร์ชันปัจจุบัน3.7.4): (1) bytearrayคาดว่าการเข้ารหัส (ไม่ใช่แค่สตริง) และ (2) map(bin, ...)จะส่งคืนmapอ็อบเจ็กต์ สำหรับจุดแรกฉันใช้เช่น. bobencoding ('ascii') `ตามที่ @Tao แนะนำ สำหรับข้อที่สองชี้โดยใช้joinวิธีการดังตัวอย่างอื่น ๆ ของ @Kasramvd จะแสดงผลลัพธ์ที่ต้องการ
Antoine

37

เราก็ต้องเข้ารหัส

'string'.encode('ascii')

สำหรับฉัน ( v3.7.4) สิ่งนี้จะส่งคืนbytesอ็อบเจ็กต์ (ด้วยการแทนค่า ascii ของแต่ละไบต์ถ้ามี) และเพื่อที่จะแสดงการแทนไบนารีของมันฉันต้องการbinเช่นด้วย' '.join(item[2:] for item in map(bin, 'bob'.encode('ascii')))(หมายเหตุที่0bต้องลบออกที่จุดเริ่มต้นของการแทนไบนารี ของตัวละครแต่ละตัว)
Antoine

15

คุณสามารถเข้าถึงค่ารหัสสำหรับอักขระในสตริงของคุณโดยใช้ord()ฟังก์ชันในตัว หากคุณต้องการจัดรูปแบบเป็นไบนารีstring.format()เมธอดจะทำงานได้

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

(ขอบคุณ Ashwini Chaudhary สำหรับการโพสต์ข้อมูลโค้ดดังกล่าว)

แม้ว่าโค้ดด้านบนจะทำงานใน 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.