Converti una stringa in binario in Python


106

Ho bisogno di un modo per ottenere la rappresentazione binaria di una stringa in Python. per esempio

st = "hello world"
toBinary(st)

Esiste un modulo di un modo pulito per farlo?


8
Quale ti aspetti che sia l'output, nello specifico?
NPE

Per "binario", intendi il tipo 0101010 o il ordnumero finale di ogni carattere in (es. Esadecimale)?
cdarke

Supponendo che tu intenda effettivamente binario (zero e uno), vuoi una rappresentazione binaria di ogni carattere (8 bit per carattere) uno dopo l'altro? ad es. h è il valore ASCII 104 sarebbe 01101000 in binario
ChrisProsser

Questa domanda è stato risposto molte volte su StackOverflow: stackoverflow.com/questions/11599226/... stackoverflow.com/questions/8553310/...
0xcaff

Risposte:


124

Qualcosa come questo?

>>> 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
O se vuoi che ogni numero binario sia 1 byte: '' .join (format (ord (i), 'b'). Zfill (8) for i in st)
ChrisProsser

5
Per i byte completi puoi anche usare ' '.join('{0:08b}'.format(ord(x), 'b') for x in st), che è circa il 35% più veloce della zfill(8)soluzione (almeno sulla mia macchina).
massimo

Che dire della conversione di caratteri più di un byte, come β, ad esempio, che mi sembra rappresentata 11001110 10110010internamente?
Sergey Bushmanov

1
So che è stato pubblicato molto tempo fa, ma per quanto riguarda i caratteri non ASCII?
pkqxdd

48

In un modo più pitonico puoi prima convertire la tua stringa in array di byte, quindi utilizzare la binfunzione all'interno map:

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

Oppure puoi unirti a esso:

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

Nota che in python3 devi specificare una codifica per la bytearrayfunzione:

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

Puoi anche usare il binasciimodulo in python 2:

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

hexlifyrestituisce la rappresentazione esadecimale dei dati binari, quindi è possibile convertirli in int specificando 16 come base, quindi convertirli in binari con bin.


5
Non solo questo è più pitonico, ma è "più" corretto per stringhe multibyte non ASCII.
Sergey Bushmanov

Solo per notare che (almeno per la versione corrente 3.7.4): (1) si bytearrayaspetta una codifica (non solo una stringa) e (2) map(bin, ...)restituirà l' mapoggetto. Per il primo punto, utilizzo ad esempio bob.encoding ('ascii') `come suggerito da @Tao. Per il secondo, punta, usando il joinmetodo, come negli altri esempi di @Kasramvd verrà visualizzato il risultato desiderato.
Antoine

36

Dobbiamo solo codificarlo.

'string'.encode('ascii')

Per me ( v3.7.4), questo restituisce un bytesoggetto (con le rappresentazioni ASCII di ogni byte, se disponibili), e per visualizzare la sua rappresentazione binaria, ho bisogno bin, ad esempio, con ' '.join(item[2:] for item in map(bin, 'bob'.encode('ascii')))(nota che 0bdeve essere rimossa all'inizio della rappresentazione binaria di ogni carattere).
Antoine

15

È possibile accedere ai valori del codice per i caratteri nella stringa utilizzando la ord()funzione incorporata. Se è quindi necessario formattarlo in binario, il string.format()metodo farà il lavoro.

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

(Grazie ad Ashwini Chaudhary per aver pubblicato lo snippet di codice.)

Sebbene il codice precedente funzioni in Python 3, la questione diventa più complicata se si presume una codifica diversa da UTF-8. In Python 2, le stringhe sono sequenze di byte e per impostazione predefinita si assume la codifica ASCII. In Python 3, si presume che le stringhe siano Unicode e c'è un bytestipo separato che si comporta più come una stringa Python 2. Se desideri assumere una codifica diversa da UTF-8, dovrai specificare la codifica.

In Python 3, quindi, puoi fare qualcosa del genere:

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

Le differenze tra la codifica UTF-8 e ascii non saranno evidenti per semplici stringhe alfanumeriche, ma diventeranno importanti se stai elaborando testo che include caratteri non presenti nel set di caratteri ascii.


2

In Python versione 3.6 e successive puoi usare f-string per formattare il risultato.

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

01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100
  • Il lato sinistro dei due punti, ord (i), è l'oggetto effettivo il cui valore verrà formattato e inserito nell'output. L'utilizzo di ord () fornisce il punto di codice in base 10 per un singolo carattere str.

  • Il lato destro dei due punti è l'identificatore di formato. 08 significa larghezza 8, 0 riempito e la b funge da segno per produrre il numero risultante in base 2 (binario).


1

Questo è un aggiornamento per le risposte esistenti che usavano bytearray()e non possono più funzionare in questo modo:

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

Perché, come spiegato nel link sopra, se la sorgente è una stringa, devi anche dare la codifica :

>>> 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 è sostanzialmente più efficiente nella conversione in un array di byte perché effettua chiamate di funzione di basso livello invece di trasformare manualmente ogni carattere in un numero intero e quindi convertire quel numero intero nel suo valore binario.


-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
Vorresti aumentare questa risposta illeggibile solo in codice con qualche spiegazione? Ciò aiuterebbe a combattere il malinteso secondo cui StackOverflow è un servizio di scrittura di codice gratuito. Nel caso in cui si desidera migliorare la leggibilità, provare le informazioni fornite qui: stackoverflow.com/editing-help
Yunnosch
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.