Convertir binario a ASCII y viceversa

Usando este código para tomar una cadena y convertirla en binario:

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

esto produce:

 0b110100001100101011011000110110001101111 

Lo cual, si lo pongo en este sitio (en el sitio de la mano derecha) recibo mi mensaje de hello . Me pregunto qué método utiliza. Sé que podría dividir la cadena del binario en 8 y luego hacerlo coincidir con el valor correspondiente a bin(ord(character)) o de alguna otra forma. Realmente buscando algo más sencillo.

Para caracteres ASCII en el rango [ -~] en Python 2:

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

En reversa:

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

En Python 3.2+:

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

En reversa:

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

Para admitir todos los caracteres Unicode en 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' 

Aquí hay una versión compatible con Python 2/3 de una sola fuente:

 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))) 

Ejemplo

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

python solo incorporado

Aquí hay un método de python puro para cuerdas simples, dejado aquí para la posteridad.

 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! 

No estoy seguro de cómo crees que puedes hacerlo aparte de carácter por carácter, es inherentemente una operación de carácter por carácter. Ciertamente, existe un código para hacer esto por usted, pero no hay una forma “más simple” que hacerlo carácter por carácter.

Primero, debe quitar el prefijo 0b y la cadena a la izquierda para que la longitud sea divisible entre 8, para facilitar la división de la cadena de bits en caracteres:

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

Luego, divide la cadena en bloques de ocho dígitos binarios, los convierte en caracteres ASCII y los une de nuevo en una cadena:

 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 realmente quiere tratarlo como un número, todavía debe tener en cuenta el hecho de que el carácter del extremo izquierdo tendrá una longitud máxima de siete dígitos si desea ir de izquierda a derecha en lugar de de derecha a izquierda.

Esta es mi manera de resolver tu tarea:

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

¿Estás buscando el código para hacerlo o entendiendo el algoritmo?

¿Esto hace lo que necesitas ? Específicamente a2b_uu y b2a_uu ? Hay MUCHAS otras opciones allí en caso de que no sean lo que quieres.

(NOTA: No es un chico de Python, pero parece una respuesta obvia)

Si no quieres importar ningún archivo, puedes usar esto:

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

para convertir un archivo de texto a binario.

y puedes usar esto para convertirlo de nuevo a cadena:

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

Espero que sea útil, lo he usado con un cifrado personalizado para enviar a través de TCP.

Esta es una versión arreglada de JF Sebastian. Gracias por los fragmentos aunque JF Sebastian.

 import binascii, sys def goodbye(): sys.exit("\n"+"*"*43+"\n\nGood Bye! Come use again!\n\n"+"*"*43+"") while __name__=='__main__': print "[A]scii to Binary, [B]inary to Ascii, or [E]xit:" var1=raw_input('>>> ') if var1=='a': string=raw_input('String to convert:\n>>> ') convert=bin(int(binascii.hexlify(string), 16)) i=2 truebin=[] while i!=len(convert): truebin.append(convert[i]) i=i+1 convert=''.join(truebin) print '\n'+'*'*84+'\n\n'+convert+'\n\n'+'*'*84+'\n' if var1=='b': binary=raw_input('Binary to convert:\n>>> ') n = int(binary, 2) done=binascii.unhexlify('%x' % n) print '\n'+'*'*84+'\n\n'+done+'\n\n'+'*'*84+'\n' if var1=='e': aus=raw_input('Are you sure? (y/n)\n>>> ') if aus=='y': goodbye()