Chuyển đổi nhị phân sang ASCII và ngược lại


82

Sử dụng mã này để lấy một chuỗi và chuyển đổi nó thành nhị phân:

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

kết quả này là:

0b110100001100101011011000110110001101111

Mà, nếu tôi đưa nó vào trang web này (trên trang web bên phải), tôi sẽ nhận được tin nhắn hellophản hồi. Tôi đang băn khoăn không biết nó sử dụng phương pháp nào. Tôi biết tôi có thể tách chuỗi nhị phân thành 8 và sau đó khớp nó với giá trị tương ứng với bin(ord(character))hoặc một số cách khác. Thực sự đang tìm kiếm thứ gì đó đơn giản hơn.


1
Vì vậy, câu hỏi của bạn, "có cách nào ngắn gọn hơn để thực hiện nghịch đảo mã của tôi hơn là cách hiển nhiên" không?
ba

1
liên quan: b2a_binphần mở rộng trong Cython cho phép tạo chuỗi nhị phân ( "01") trực tiếp từ các bytestrings mà không cần tạo số nguyên Python trung gian.
jfs

Câu trả lời:


158

Đối với các ký tự ASCII trong phạm vi [ -~]trên Python 2:

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

Ngược lại:

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

Trong Python 3.2+:

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

Ngược lại:

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

Để hỗ trợ tất cả các ký tự Unicode trong 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'

Đây là phiên bản tương thích Python 2/3 nguồn đơn:

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

Thí dụ

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

3
@JFSebastian Tôi đã thử phương pháp này với phiên bản hiện tại của python và có vẻ như nó không hoạt động. <br/> TypeError: 'str' không hỗ trợ giao diện đệm <br/> Bạn có cập nhật câu trả lời của mình không
hamza

3
@hamza: Nó hoạt động trên Python 2. Trên Python 3 bạn nên chuyển đổi str để byte ví dụ đầu tiên,your_string.encode('ascii', 'strict')
JFS

1
@JFSebasitian: cảm ơn, tuy nhiên khi tôi đã thử thì ngược lại, funtion không xác thực trả về thông báo lỗi: binascii.Error: Odd-length string.
hamza

3
@hamza: thêm nó với '0'nếu độ dài của chuỗi hex không bằng nhau. Nó xảy ra nếu ký tự đầu tiên trong chuỗi gốc có mã ascii nhỏ hơn 16, ví dụ: '\n'hoặc '\t'. Độ dài kỳ lạ không bao giờ xảy ra đối với các chữ cái ascii [ -~].
jfs 14/11/12

22

Built-in chỉpython

Đây là một phương pháp python thuần túy cho các chuỗi đơn giản, để lại ở đây cho hậu thế.

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!

2
chr (int ()) là những gì tôi đang tìm kiếm!
JqueryToAddNumbers

Chính xác những gì tôi cũng đang tìm kiếm !!
Joachim

9

Tôi không chắc bạn nghĩ bạn có thể làm điều đó như thế nào ngoài từng ký tự - nó vốn dĩ là hoạt động của từng ký tự. Chắc chắn có mã để làm điều này cho bạn, nhưng không có cách nào "đơn giản" hơn là thực hiện theo từng ký tự.

Trước tiên, bạn cần tách 0btiền tố và nhấn phím trái-0 vào chuỗi để độ dài của nó chia hết cho 8, để dễ dàng chia chuỗi bit thành các ký tự:

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

Sau đó, bạn chia chuỗi thành các khối gồm tám chữ số nhị phân, chuyển đổi chúng thành các ký tự ASCII và nối chúng lại thành một chuỗi:

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)

Nếu bạn thực sự muốn coi nó là một số, bạn vẫn phải tính đến thực tế là ký tự ngoài cùng bên trái sẽ dài tối đa bảy chữ số nếu bạn muốn chuyển từ trái sang phải thay vì từ phải sang trái.


2

Đây là cách của tôi để giải quyết nhiệm vụ của bạn:

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

Tại sao bạn thêm '0' tại str = "0" + str [2:] ?. 0b là cần thiết để loại bỏ ở đây vì nó đang bắt đầu.
bimlesh sharma

2

nếu bạn không muốn nhập bất kỳ tệp nào, bạn có thể sử dụng cái này:

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

để chuyển đổi tệp văn bản thành tệp nhị phân.

và bạn có thể sử dụng điều này để chuyển đổi nó trở lại thành chuỗi:

StrOrgList = StrOrgMsg.split(" ")


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

hy vọng điều đó hữu ích, tôi đã sử dụng điều này với một số mã hóa tùy chỉnh để gửi qua TCP.


1

Bạn đang tìm kiếm mã để làm điều đó hoặc hiểu thuật toán?

Điều này có làm những gì bạn cần ? Cụ thể a2b_uub2a_uu? Có RẤT NHIỀU tùy chọn khác trong trường hợp đó không phải là những gì bạn muốn.

(LƯU Ý: Không phải là một chàng trai Python nhưng đây dường như là một câu trả lời hiển nhiên)


Tôi đã nghiên cứu nó một chút, binascii không làm việc cho tôi, và chủ yếu là tìm kiếm mã, nếu tôi có thể nhìn thấy nó, tôi có thể hiểu nó. Mặc dù vậy, cảm ơn EDIT: khi chuyển đổi ascii sang nhị phân bằng binascii a2b_uu cho "h" là \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00, đây không phải là thứ tôi cần, tôi cần 'xin chào' và số 1 và số 0 thực tế không shellcode tìm ascii, cũng có thể nó chỉ có tác dụng char của char
sbrichards

@Jaxidian khá hữu ích cho mục đích của tôi. Ai đó đã lưu trữ một số dữ liệu trong một chuỗi và tôi có nó. Tôi khá chắc chắn rằng đó là b / c 64binary của phần đệm. Tôi có thể sử dụng thành công b2a_base64trên đó, tuy nhiên, kết quả thực sự là khó hiểu. Làm cách nào để lấy danh sách boollean / số nguyên (0,1) từ đó?
Ufos

0

Chuyển đổi nhị phân sang ký tự tương đương của nó.

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

-1

Đây là một phiên bản tạo ra của JF Sebastian. Cảm ơn vì những đoạn trích 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()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.