Czy przez „binarny” masz na myśli typ 0101010, czy też inal ordnumer każdego znaku (np. Szesnastkowy)?
cdarke
Zakładając, że faktycznie masz na myśli binarne (zera i jedynki), czy chcesz binarną reprezentację każdego znaku (8 bitów na znak) jeden po drugim? np. h to ascii, wartość 104 byłaby binarna jako 01101000
Lub jeśli chcesz, aby każda liczba binarna miała 1 bajt: '' .join (format (ord (i), 'b'). Zfill (8) for i in st)
ChrisProsser
5
Do pełnych bajtów można również użyć ' '.join('{0:08b}'.format(ord(x), 'b') for x in st), co jest około 35% szybsze niż zfill(8)rozwiązanie (przynajmniej na moim komputerze).
maks.
A co z konwersją znaków więcej niż jednobajtowych β, na przykład, które wydają mi się reprezentowane przez 11001110 10110010wewnętrznie?
Sergey Bushmanov
1
Wiem, że to zostało opublikowane dawno temu, ale co ze znakami spoza ASCII?
pkqxdd
48
W bardziej Pythonowym sposobie możesz najpierw przekonwertować swój ciąg na tablicę bajtów, a następnie użyć binfunkcji w map:
>>> st ="hello world">>> map(bin,bytearray(st))['0b1101000','0b1100101','0b1101100','0b1101100','0b1101111','0b100000','0b1110111','0b1101111','0b1110010','0b1101100','0b1100100']
hexlifyzwróć szesnastkową reprezentację danych binarnych, a następnie możesz przekonwertować je na int, określając 16 jako podstawę, a następnie przekonwertuj je na binarne za pomocą bin.
Nie tylko jest to bardziej pythonowe, ale jest „bardziej” poprawne dla wielobajtowych ciągów innych niż ASCII.
Sergey Bushmanov
Wystarczy zauważyć, że (przynajmniej dla bieżącej wersji 3.7.4): (1) bytearrayoczekuje kodowania (nie tylko ciągu znaków), a (2) map(bin, ...)zwróci mapobiekt. W pierwszym punkcie używam na przykład bob.encoding ('ascii') `zgodnie z sugestią @Tao. Po drugie, wskaż, używając joinmetody, tak jak w innych przykładach @Kasramvd wyświetli pożądany wynik.
Dla mnie ( v3.7.4) zwraca to bytesobiekt (z reprezentacjami ascii każdego bajtu, jeśli jest dostępny), a żeby wyświetlić jego binarną reprezentację potrzebuję binnp. With ' '.join(item[2:] for item in map(bin, 'bob'.encode('ascii')))(uwaga, którą 0bnależy usunąć na początku reprezentacji binarnej każdego znaku).
Antoine,
15
Możesz uzyskać dostęp do wartości kodu dla znaków w ciągu za pomocą funkcji ord()wbudowanej. Jeśli potem będziesz musiał sformatować to w formacie binarnym, string.format()metoda wykona zadanie.
a ="test"print(' '.join(format(ord(x),'b')for x in a))
(Podziękowania dla Ashwini Chaudhary za opublikowanie tego fragmentu kodu).
Chociaż powyższy kod działa w Pythonie 3, sprawa staje się bardziej skomplikowana, jeśli zakładasz kodowanie inne niż UTF-8. W Pythonie 2 ciągi są sekwencjami bajtów i domyślnie zakłada się kodowanie ASCII. W Pythonie 3 przyjmuje się, że łańcuchy są kodami Unicode i istnieje oddzielny bytestyp, który działa bardziej jak łańcuch w Pythonie 2. Jeśli chcesz założyć kodowanie inne niż UTF-8, musisz określić kodowanie.
W Pythonie 3 możesz więc zrobić coś takiego:
a ="test"
a_bytes = bytes(a,"ascii")print(' '.join(["{0:b}".format(x)for x in a_bytes]))
Różnice między kodowaniem UTF-8 i ascii nie będą oczywiste w przypadku prostych ciągów alfanumerycznych, ale staną się ważne, jeśli przetwarzasz tekst zawierający znaki spoza zestawu znaków ascii.
W Pythonie w wersji 3.6 i nowszych możesz użyć f-string do sformatowania wyniku.
str ="hello world"print(" ".join(f"{ord(i):08b}"for i in str))0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100
Lewa strona dwukropka, ord (i), to rzeczywisty obiekt, którego wartość zostanie sformatowana i wstawiona do wyniku. Użycie ord () daje punkt kodowy przy podstawie 10 dla pojedynczego znaku str.
Prawa strona dwukropka to specyfikator formatu. 08 oznacza szerokość 8, 0 wypełnione, a b działa jako znak, aby wyprowadzić wynikową liczbę w bazie 2 (binarnie).
To jest aktualizacja istniejących odpowiedzi, które były używane bytearray()i nie mogą już działać w ten sposób:
>>> st ="hello world">>> map(bin, bytearray(st))Traceback(most recent call last):File"<stdin>", line 1,in<module>TypeError: string argument without an encoding
Ponieważ, jak wyjaśniono w powyższym linku, jeśli źródłem jest ciąg, musisz również podać kodowanie :
>>> map(bin, bytearray(st, encoding='utf-8'))<map object at 0x7f14dfb1ff28>
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
Metoda method_b jest znacznie bardziej wydajna w konwertowaniu na tablicę bajtów, ponieważ wykonuje wywołania funkcji niskiego poziomu, zamiast ręcznie przekształcać każdy znak na liczbę całkowitą, a następnie konwertować tę liczbę całkowitą na jej wartość binarną.
Czy chciałbyś rozszerzyć tę nieczytelną odpowiedź zawierającą tylko kod o jakieś wyjaśnienie? Pomogłoby to w zwalczaniu błędnego przekonania, że StackOverflow to bezpłatna usługa pisania kodu. Jeśli chcesz poprawić czytelność, wypróbuj informacje podane tutaj: stackoverflow.com/editing-help
ord
numer każdego znaku (np. Szesnastkowy)?Odpowiedzi:
Coś takiego?
źródło
' '.join('{0:08b}'.format(ord(x), 'b') for x in st)
, co jest około 35% szybsze niżzfill(8)
rozwiązanie (przynajmniej na moim komputerze).β
, na przykład, które wydają mi się reprezentowane przez11001110 10110010
wewnętrznie?W bardziej Pythonowym sposobie możesz najpierw przekonwertować swój ciąg na tablicę bajtów, a następnie użyć
bin
funkcji wmap
:Lub możesz do niego dołączyć:
Zauważ, że w python3 musisz określić kodowanie
bytearray
funkcji:Możesz także użyć
binascii
modułu w Pythonie 2:hexlify
zwróć szesnastkową reprezentację danych binarnych, a następnie możesz przekonwertować je na int, określając 16 jako podstawę, a następnie przekonwertuj je na binarne za pomocąbin
.źródło
3.7.4
): (1)bytearray
oczekuje kodowania (nie tylko ciągu znaków), a (2)map(bin, ...)
zwrócimap
obiekt. W pierwszym punkcie używam na przykładbob
.encoding ('ascii') `zgodnie z sugestią @Tao. Po drugie, wskaż, używającjoin
metody, tak jak w innych przykładach @Kasramvd wyświetli pożądany wynik.Musimy to tylko zakodować.
źródło
v3.7.4
) zwraca tobytes
obiekt (z reprezentacjami ascii każdego bajtu, jeśli jest dostępny), a żeby wyświetlić jego binarną reprezentację potrzebujębin
np. With' '.join(item[2:] for item in map(bin, 'bob'.encode('ascii')))
(uwaga, którą0b
należy usunąć na początku reprezentacji binarnej każdego znaku).Możesz uzyskać dostęp do wartości kodu dla znaków w ciągu za pomocą funkcji
ord()
wbudowanej. Jeśli potem będziesz musiał sformatować to w formacie binarnym,string.format()
metoda wykona zadanie.(Podziękowania dla Ashwini Chaudhary za opublikowanie tego fragmentu kodu).
Chociaż powyższy kod działa w Pythonie 3, sprawa staje się bardziej skomplikowana, jeśli zakładasz kodowanie inne niż UTF-8. W Pythonie 2 ciągi są sekwencjami bajtów i domyślnie zakłada się kodowanie ASCII. W Pythonie 3 przyjmuje się, że łańcuchy są kodami Unicode i istnieje oddzielny
bytes
typ, który działa bardziej jak łańcuch w Pythonie 2. Jeśli chcesz założyć kodowanie inne niż UTF-8, musisz określić kodowanie.W Pythonie 3 możesz więc zrobić coś takiego:
Różnice między kodowaniem UTF-8 i ascii nie będą oczywiste w przypadku prostych ciągów alfanumerycznych, ale staną się ważne, jeśli przetwarzasz tekst zawierający znaki spoza zestawu znaków ascii.
źródło
W Pythonie w wersji 3.6 i nowszych możesz użyć f-string do sformatowania wyniku.
Lewa strona dwukropka, ord (i), to rzeczywisty obiekt, którego wartość zostanie sformatowana i wstawiona do wyniku. Użycie ord () daje punkt kodowy przy podstawie 10 dla pojedynczego znaku str.
Prawa strona dwukropka to specyfikator formatu. 08 oznacza szerokość 8, 0 wypełnione, a b działa jako znak, aby wyprowadzić wynikową liczbę w bazie 2 (binarnie).
źródło
To jest aktualizacja istniejących odpowiedzi, które były używane
bytearray()
i nie mogą już działać w ten sposób:Ponieważ, jak wyjaśniono w powyższym linku, jeśli źródłem jest ciąg, musisz również podać kodowanie :
źródło
Metoda method_b jest znacznie bardziej wydajna w konwertowaniu na tablicę bajtów, ponieważ wykonuje wywołania funkcji niskiego poziomu, zamiast ręcznie przekształcać każdy znak na liczbę całkowitą, a następnie konwertować tę liczbę całkowitą na jej wartość binarną.
źródło
źródło