J'ai besoin d'un moyen d'obtenir la représentation binaire d'une chaîne en python. par exemple.
st = "hello world"
toBinary(st)
Existe-t-il un module sur un moyen astucieux de procéder?
Quelque chose comme ça?
>>> 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))
'1101000 1100101 1101100 1101100 1101111 100000 1110111 1101111 1110010 1101100 1100100'
De manière plus pythonique, vous pouvez d’abord convertir votre chaîne en tableau d’octets, puis utiliser la fonction bin
dans map
:
>>> st = "hello world"
>>> map(bin,bytearray(st))
['0b1101000', '0b1100101', '0b1101100', '0b1101100', '0b1101111', '0b100000', '0b1110111', '0b1101111', '0b1110010', '0b1101100', '0b1100100']
Ou vous pouvez le rejoindre:
>>> ' '.join(map(bin,bytearray(st)))
'0b1101000 0b1100101 0b1101100 0b1101100 0b1101111 0b100000 0b1110111 0b1101111 0b1110010 0b1101100 0b1100100'
Notez que dans python3 vous devez spécifier un encodage pour la fonction bytearray
:
>>> ' '.join(map(bin,bytearray(st,'utf8')))
'0b1101000 0b1100101 0b1101100 0b1101100 0b1101111 0b100000 0b1110111 0b1101111 0b1110010 0b1101100 0b1100100'
Vous pouvez également utiliser le module binascii
dans Python 2:
>>> import binascii
>>> bin(int(binascii.hexlify(st),16))
'0b110100001100101011011000110110001101111001000000111011101101111011100100110110001100100'
hexlify
renvoie la représentation hexadécimale des données binaires. Vous pouvez ensuite convertir en int en spécifiant 16 comme base puis la convertir en binaire avec bin
.
Vous pouvez accéder aux valeurs de code pour les caractères de votre chaîne à l'aide de la fonction intégrée ord()
. Si vous devez ensuite formater ceci en binaire, la méthode string.format()
fera le travail.
a = "test"
print(' '.join(format(ord(x), 'b') for x in a))
(Merci à Ashwini Chaudhary pour la publication de cet extrait de code.)
Bien que le code ci-dessus fonctionne dans Python 3, le problème devient plus compliqué si vous supposez un encodage autre que UTF-8. En Python 2, les chaînes sont des séquences d'octets et le codage ASCII est supposé par défaut. Dans Python 3, les chaînes sont supposées être au format Unicode et il existe un type bytes
distinct qui agit davantage comme une chaîne Python 2. Si vous souhaitez utiliser un codage autre que UTF-8, vous devez le spécifier.
En Python 3, vous pouvez faire quelque chose comme ceci:
a = "test"
a_bytes = bytes(a, "ascii")
print(' '.join(["{0:b}".format(x) for x in a_bytes]))
Les différences entre le codage UTF-8 et le codage ascii ne seront pas évidentes pour les chaînes alphanumériques simples, mais deviendront importantes si vous traitez un texte comprenant des caractères ne faisant pas partie du jeu de caractères ascii.
Nous avons juste besoin de l'encoder.
'string'.encode('ascii')
Ceci est une mise à jour des réponses existantes qui utilisaient bytearray()
et ne peuvent plus fonctionner ainsi:
>>> st = "hello world"
>>> map(bin, bytearray(st))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding
Parce que, comme expliqué dans le lien ci-dessus, si la source est une chaîne, vous devez également indiquer le codage:
>>> map(bin, bytearray(st, encoding='utf-8'))
<map object at 0x7f14dfb1ff28>
Dans Python version 3.6 et ultérieure, vous pouvez utiliser 'f-string' pour formater le résultat.
str = "hello world"
print(" ".join(f"{ord(i):08b}" for i in str))
01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100
Le côté gauche des deux points, ord (i), est l'objet réel dont la valeur sera formatée et insérée dans la sortie. Utiliser ord () vous donne le point de code base-10 pour un seul caractère str.
Le côté droit des deux-points est le spécificateur de format. 08 correspond à la largeur 8, le 0 est complété et le b sert de signe pour afficher le nombre obtenu en base 2 (binaire).
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 __== '__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 convertit beaucoup plus efficacement en tableau d'octets, car il appelle des fonctions de bas niveau au lieu de transformer manuellement chaque caractère en entier, puis de le convertir en valeur binaire.