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.