Преобразование двоичных файлов в ASCII и наоборот

Используя этот код, чтобы взять строку и преобразовать ее в двоичный:

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

эти выходы:

0b110100001100101011011000110110001101111

Что, если я помещу его в этот сайт (на правом сайте), я получаю сообщение hello назад. Мне интересно, какой метод он использует. Я знаю, что я мог бы объединить строку двоичного кода в 8, а затем сопоставить ее с соответствующим значением bin(ord(character)) или каким-либо другим способом. Действительно ищет что-то более простое.

Ответ 1

Для символов ASCII в диапазоне [ -~] на Python 2:

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

В обратном порядке:

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

В Python 3.2 +:

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

В обратном порядке:

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

Для поддержки всех символов Unicode в 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'

Здесь версия с одним источником 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)))

Пример

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

Ответ 2

Я не уверен, как вы думаете, что вы можете делать это иначе, чем посимвольный характер - по сути своей это характерная операция. Конечно, есть код, чтобы сделать это для вас, но нет "более простого" способа, чем его по-символу.

Во-первых, вам нужно разбить префикс 0b и left-zero-pad на строку, чтобы длина делилась на 8, чтобы облегчить разделение битовой строки на символы:

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

Затем вы разделите строку на блоки из восьми двоичных цифр, преобразуете их в символы ASCII и присоедините их обратно к строке:

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)

Если вы действительно хотите рассматривать его как число, вам все равно придется учитывать тот факт, что самый левый символ будет содержать не более семи цифр, если вы хотите идти слева направо, а не справа налево.

Ответ 3

Только встроенный python

Вот чистый метод python для простых строк, оставленный здесь для потомков.

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!

Ответ 4

Это мой способ решить вашу задачу:

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

Ответ 5

Вы ищете код для этого или понимаете алгоритм?

Делает ли это то, что вам нужно? В частности a2b_uu и b2a_uu? Есть много других вариантов там, если они не то, что вы хотите.

(ПРИМЕЧАНИЕ: не парень Python, но это казалось очевидным ответом)

Ответ 6

если вы не хотите импортировать какие-либо файлы, вы можете использовать это:

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

для преобразования текстового файла в двоичный файл.

и вы можете использовать его для преобразования в строку:

StrOrgList = StrOrgMsg.split(" ")


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

надеюсь, что это полезно, я использовал это с помощью специального пользовательского шифрования для отправки через TCP.

Ответ 7

Это пряная версия Дж. Ф. Себастьяна. Спасибо за фрагменты, хотя Я. Ф. Себастьян.

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