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?

user1090614
quelle
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'
Ashwini Chaudhary
quelle
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.

Kasravnd
quelle
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')
Tao
quelle
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.

Mark R. Wilkins
quelle
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.

Vlad Bezden
quelle
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>
Billal Begueradj
quelle
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.

Ben
quelle
-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))
Solo Schiff
quelle
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