Konvertieren Sie eine Zeichenfolge in eine Binärdatei in Python


106

Ich brauche eine Möglichkeit, die binäre Darstellung eines Strings in Python zu erhalten. z.B

st = "hello world"
toBinary(st)

Gibt es ein Modul, mit dem man das ordentlich machen kann?


8
Was erwarten Sie konkret von der Ausgabe?
— NPE

Mit "binär" meinen Sie den Typ 0101010 oder die ordEndnummer jedes Zeichens in (z. B. hexadezimal)?
— Cdarke

Angenommen, Sie meinen tatsächlich binär (Nullen und Einsen), möchten Sie eine binäre Darstellung jedes Zeichens (8 Bits pro Zeichen) nacheinander? zB h ist ascii Wert 104 wäre 01101000 in binär
— ChrisProsser

Diese Frage wurde viele Male auf stackoverflow beantwortet: stackoverflow.com/questions/11599226/… stackoverflow.com/questions/8553310/…
— 0xcaff

Antworten:


124

Etwas wie das?

>>> 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
Oder wenn Sie möchten, dass jede Binärzahl 1 Byte ist: '' .join (Format (ord (i), 'b'). Zfill (8) für i in st)
— ChrisProsser

5
Für volle Bytes können Sie auch verwenden ' '.join('{0:08b}'.format(ord(x), 'b') for x in st), was etwa 35% schneller als die zfill(8)Lösung ist (zumindest auf meinem Computer).
— Max

Was ist mit der Konvertierung von Zeichen mit mehr als einem Byte, wie βz. B. das, was mir 11001110 10110010intern dargestellt wird?
— Sergey Bushmanov

1
Ich weiß, dass dies vor langer Zeit gepostet wurde, aber was ist mit Nicht-ASCII-Zeichen?
— pkqxdd

48

Als pythonischere Methode können Sie Ihre Zeichenfolge zuerst in ein Byte-Array konvertieren und dann die folgende binFunktion verwenden map:

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

Oder du kannst mitmachen:

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

Beachten Sie, dass Sie in Python3 eine Codierung für die bytearrayFunktion angeben müssen:

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

Sie können das binasciiModul auch in Python 2 verwenden:

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

hexlifyGeben Sie die hexadezimale Darstellung der Binärdaten zurück. Anschließend können Sie sie in int konvertieren, indem Sie 16 als Basis angeben und sie dann mit in binär konvertieren bin.


5
Dies ist nicht nur pythonischer, sondern auch "korrekter" für Multi-Byte-Nicht-ASCII-Zeichenfolgen.
— Sergey Bushmanov

Nur um zu beachten, dass (zumindest für die aktuelle Version 3.7.4): (1) bytearrayeine Codierung (nicht nur eine Zeichenfolge) erwartet und (2) map(bin, ...)das mapObjekt zurückgibt. Für den ersten Punkt verwende ich zum Beispiel bob.encoding ('ascii') `, wie von @Tao vorgeschlagen. Für den zweiten Punkt zeigt die Verwendung der joinMethode wie in den anderen Beispielen von @Kasramvd das gewünschte Ergebnis an.
— Antoine

34

Wir müssen es nur verschlüsseln.

'string'.encode('ascii')

Für mich ( v3.7.4) gibt dies ein bytesObjekt zurück (mit den ASCII-Darstellungen jedes Bytes, falls verfügbar), und um seine Binärdarstellung anzuzeigen, benötige ich binz. B. mit ' '.join(item[2:] for item in map(bin, 'bob'.encode('ascii')))(Hinweis, der 0bam Anfang der Binärdarstellung entfernt werden muss jedes Zeichens).
— Antoine

15

Sie können mit der ord()integrierten Funktion auf die Codewerte für die Zeichen in Ihrer Zeichenfolge zugreifen . Wenn Sie dies dann binär formatieren müssen, erledigt die string.format()Methode die Aufgabe.

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

(Vielen Dank an Ashwini Chaudhary für das Posten dieses Code-Snippets.)

Während der obige Code in Python 3 funktioniert, wird diese Angelegenheit komplizierter, wenn Sie eine andere Codierung als UTF-8 annehmen. In Python 2 sind Zeichenfolgen Bytefolgen, und die ASCII-Codierung wird standardmäßig angenommen. In Python 3 wird angenommen, dass Zeichenfolgen Unicode sind, und es gibt einen separaten bytesTyp, der sich eher wie eine Python 2-Zeichenfolge verhält. Wenn Sie eine andere Codierung als UTF-8 annehmen möchten, müssen Sie die Codierung angeben.

In Python 3 können Sie also Folgendes tun:

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

Die Unterschiede zwischen UTF-8- und ASCII-Codierung sind für einfache alphanumerische Zeichenfolgen nicht offensichtlich, werden jedoch wichtig, wenn Sie Text verarbeiten, der Zeichen enthält, die nicht im ASCII-Zeichensatz enthalten sind.


2

In Python Version 3.6 und höher können Sie f-string verwenden, um das Ergebnis zu formatieren.

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

01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100
  • Die linke Seite des Doppelpunkts, ord (i), ist das eigentliche Objekt, dessen Wert formatiert und in die Ausgabe eingefügt wird. Mit ord () erhalten Sie den Basis-10-Codepunkt für ein einzelnes str-Zeichen.

  • Die rechte Seite des Doppelpunkts ist der Formatbezeichner. 08 bedeutet Breite 8, 0 aufgefüllt, und das b fungiert als Vorzeichen, um die resultierende Zahl in Basis 2 (binär) auszugeben.


1

Dies ist ein Update für die vorhandenen Antworten, die verwendet wurden bytearray()und nicht mehr so ​​funktionieren können:

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

Denn wie im obigen Link erläutert, müssen Sie , wenn die Quelle eine Zeichenfolge ist, auch die folgende Codierung angeben :

>>> 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 konvertiert wesentlich effizienter in ein Byte-Array, da es Funktionsaufrufe auf niedriger Ebene ausführt, anstatt jedes Zeichen manuell in eine Ganzzahl umzuwandeln und diese Ganzzahl dann in ihren Binärwert umzuwandeln.


-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
Möchten Sie diese unlesbare Nur-Code-Antwort mit einer Erklärung ergänzen? Dies würde helfen, das Missverständnis zu bekämpfen, dass StackOverflow ein kostenloser Dienst zum Schreiben von Code ist. Wenn
— Yunnosch
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.