web-dev-qa-db-fra.com

Convertir les fichiers binaires en ASCII et vice versa

Utiliser ce code pour prendre une chaîne et la convertir en binaire:

bin(reduce(lambda x, y: 256*x+y, (ord(c) for c in 'hello'), 0))

cette sortie:

0b110100001100101011011000110110001101111

Si je le mets dans ce site (sur le site de droite), je reçois mon message de hello. Je me demande quelle méthode il utilise. Je sais que je pourrais séparer la chaîne de binaire en 8, puis la faire correspondre à la valeur correspondante à bin(ord(character)) ou à un autre moyen. Vraiment chercher quelque chose de plus simple.

69
sbrichards

Pour ASCII caractères dans la plage [ -~] on Python 2:

>>> import binascii
>>> bin(int(binascii.hexlify('hello'), 16))
'0b110100001100101011011000110110001101111'

En marche arrière:

>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> binascii.unhexlify('%x' % n)
'hello'

Dans Python 3.2+:

>>> bin(int.from_bytes('hello'.encode(), 'big'))
'0b110100001100101011011000110110001101111'

En marche arrière:

>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big').decode()
'hello'

Pour prendre en charge tous les caractères Unicode dans Python 3:

def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
    bits = bin(int.from_bytes(text.encode(encoding, errors), 'big'))[2:]
    return bits.zfill(8 * ((len(bits) + 7) // 8))

def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
    n = int(bits, 2)
    return n.to_bytes((n.bit_length() + 7) // 8, 'big').decode(encoding, errors) or '\0'

Voici une source unique Python 2/3:

import binascii

def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
    bits = bin(int(binascii.hexlify(text.encode(encoding, errors)), 16))[2:]
    return bits.zfill(8 * ((len(bits) + 7) // 8))

def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
    n = int(bits, 2)
    return int2bytes(n).decode(encoding, errors)

def int2bytes(i):
    hex_string = '%x' % i
    n = len(hex_string)
    return binascii.unhexlify(hex_string.zfill(n + (n & 1)))

Exemple

>>> text_to_bits('hello')
'0110100001100101011011000110110001101111'
>>> text_from_bits('110100001100101011011000110110001101111') == u'hello'
True
141
jfs

Intégré seulement python

Voici une méthode pure python pour les chaînes simples, laissée ici pour la postérité.

def string2bits(s=''):
    return [bin(ord(x))[2:].zfill(8) for x in s]

def bits2string(b=None):
    return ''.join([chr(int(x, 2)) for x in b])

s = 'Hello, World!'
b = string2bits(s)
s2 = bits2string(b)

print 'String:'
print s

print '\nList of Bits:'
for x in b:
    print x

print '\nString:'
print s2

String:
Hello, World!

List of Bits:
01001000
01100101
01101100
01101100
01101111
00101100
00100000
01010111
01101111
01110010
01101100
01100100
00100001

String:
Hello, World!
14
tmthydvnprt

Je ne sais pas comment vous pensez pouvoir le faire autrement que caractère par caractère - il s'agit fondamentalement d'une opération caractère par caractère. Il y a certainement du code pour le faire pour vous, mais il n'y a pas de moyen "plus simple" que de le faire personnage par caractère.

Tout d'abord, vous devez dépouiller le 0b préfixe, et left-zero-pad pour que la longueur de la chaîne soit divisible par 8, ce qui facilite la division de la chaîne de bits en caractères:

bitstring = bitstring[2:]
bitstring = -len(bitstring) % 8 * '0' + bitstring

Ensuite, vous divisez la chaîne en blocs de huit chiffres binaires, vous les convertissez en caractères ASCII) et vous les associez à nouveau en une chaîne:

string_blocks = (bitstring[i:i+8] for i in range(0, len(bitstring), 8))
string = ''.join(chr(int(char, 2)) for char in string_blocks)

Si vous voulez réellement le traiter comme un nombre, vous devez toujours prendre en compte le fait que le caractère le plus à gauche aura au plus sept chiffres si vous voulez aller de gauche à droite au lieu de droite à gauche.

9
agf

si vous ne souhaitez pas importer de fichiers, vous pouvez utiliser ceci:

with open("Test1.txt", "r") as File1:
St = (' '.join(format(ord(x), 'b') for x in File1.read()))
StrList = St.split(" ")

convertir un fichier texte en binaire.

et vous pouvez l'utiliser pour le reconvertir en chaîne:

StrOrgList = StrOrgMsg.split(" ")


for StrValue in StrOrgList:
    if(StrValue != ""):
        StrMsg += chr(int(str(StrValue),2))
print(StrMsg)

j'espère que cela est utile, j'ai utilisé cela avec un cryptage personnalisé pour envoyer sur TCP.

2
Kyle Burns

Ceci est ma façon de résoudre votre tâche:

str = "0b110100001100101011011000110110001101111"
str = "0" + str[2:]
message = ""
while str != "":
    i = chr(int(str[:8], 2))
    message = message + i
    str = str[8:]
print message
2

Cherchez-vous le code pour le faire ou comprenez l'algorithme?

Cela fait-il ce dont vous avez besoin ? Plus précisément a2b_uu et b2a_uu? Il y a BEAUCOUP d'autres options dans le cas où ce ne sont pas ce que vous voulez.

(NOTE: Pas un gars Python mais cela semblait être une réponse évidente)

1
Jaxidian