Convert binary to ASCII and vice versa
Using this code to take a string and convert it to binary:
bin(reduce(lambda x, y: 256*x+y, (ord(c) for c in 'hello'), 0))
this outputs:
0b110100001100101011011000110110001101111
Which, if I put it into this site (on the right hand site) I get my message of hello
back. I'm wondering what method it uses. I know I could splice apart the string of binary into 8's and then match it to the c开发者_StackOverflow中文版orresponding value to bin(ord(character))
or some other way. Really looking for something simpler.
For ASCII characters in the range [ -~]
on Python 2:
>>> import binascii
>>> bin(int(binascii.hexlify('hello'), 16))
'0b110100001100101011011000110110001101111'
In reverse:
>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> binascii.unhexlify('%x' % n)
'hello'
In Python 3.2+:
>>> bin(int.from_bytes('hello'.encode(), 'big'))
'0b110100001100101011011000110110001101111'
In reverse:
>>> n = int('0b110100001100101011011000110110001101111', 2)
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big').decode()
'hello'
To support all Unicode characters in 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'
Here's single-source Python 2/3 compatible version:
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)))
Example
>>> text_to_bits('hello')
'0110100001100101011011000110110001101111'
>>> text_from_bits('110100001100101011011000110110001101111') == u'hello'
True
Built-in only python
Here is a pure python method for simple strings, left here for posterity.
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!
I'm not sure how you think you can do it other than character-by-character -- it's inherently a character-by-character operation. There is certainly code out there to do this for you, but there is no "simpler" way than doing it character-by-character.
First, you need to strip the 0b
prefix, and left-zero-pad the string so it's length is divisible by 8, to make dividing the bitstring up into characters easy:
bitstring = bitstring[2:]
bitstring = -len(bitstring) % 8 * '0' + bitstring
Then you divide the string up into blocks of eight binary digits, convert them to ASCII characters, and join them back into a string:
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)
If you actually want to treat it as a number, you still have to account for the fact that the leftmost character will be at most seven digits long if you want to go left-to-right instead of right-to-left.
This is my way to solve your task:
str = "0b110100001100101011011000110110001101111"
str = "0" + str[2:]
message = ""
while str != "":
i = chr(int(str[:8], 2))
message = message + i
str = str[8:]
print message
if you don'y want to import any files you can use this:
with open("Test1.txt", "r") as File1:
St = (' '.join(format(ord(x), 'b') for x in File1.read()))
StrList = St.split(" ")
to convert a text file to binary.
and you can use this to convert it back to string:
StrOrgList = StrOrgMsg.split(" ")
for StrValue in StrOrgList:
if(StrValue != ""):
StrMsg += chr(int(str(StrValue),2))
print(StrMsg)
hope that is helpful, i've used this with some custom encryption to send over TCP.
Are you looking for the code to do it or understanding the algorithm?
Does this do what you need? Specifically a2b_uu
and b2a_uu
? There are LOTS of other options in there in case those aren't what you want.
(NOTE: Not a Python guy but this seemed like an obvious answer)
Convert binary to its equivalent character.
k=7
dec=0
new=[]
item=[x for x in input("Enter 8bit binary number with , seprator").split(",")]
for i in item:
for j in i:
if(j=="1"):
dec=2**k+dec
k=k-1
else:
k=k-1
new.append(dec)
dec=0
k=7
print(new)
for i in new:
print(chr(i),end="")
This is a spruced up version of J.F. Sebastian's. Thanks for the snippets though J.F. 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()
精彩评论