바이너리를 ASCII로 또는 그 반대로 변환


82

이 코드를 사용하여 문자열을 가져 와서 바이너리로 변환합니다.

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

이 출력 :

0b110100001100101011011000110110001101111

이 사이트 (오른쪽 사이트)에 넣으면 내 메시지가 hello돌아옵니다. 어떤 방법을 사용하는지 궁금합니다. 바이너리 문자열을 8로 분리 한 다음 해당 값 bin(ord(character))또는 다른 방식으로 일치시킬 수 있다는 것을 알고 있습니다. 정말 더 간단한 것을 찾고 있습니다.


1
그래서 당신의 질문은 "명백한 것보다 내 코드의 역을 수행하는 더 간결한 방법이 있는가"입니까?
tripleee 2011 년

1
관련 : b2a_binCython의 확장 을 사용 "01"하면 중간 Python 정수를 만들지 않고도 바이트 문자열 에서 직접 이진 문자열 ( ) 을 만들 수 있습니다 .
jfs

답변:


158

[ -~]Python 2 의 범위 에 있는 ASCII 문자의 경우 :

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

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

3
@JFSebastian 나는 파이썬 현재 버전 에서이 방법을 시도했지만 작동하지 않는 것 같습니다. <br/> TypeError : 'str'은 버퍼 인터페이스를 지원하지 않습니다. <br/> 답변을 업데이트 하시겠습니까
hamza

3
@hamza : Python 2에서 작동합니다. Python 3에서는 str을 먼저 바이트로 변환해야합니다. 예 :your_string.encode('ascii', 'strict')
jfs

1
@JFSebasitian : 감사합니다,하지만 반대로 시도했을 때 unhexlify 함수는 오류 메시지를 반환합니다 : binascii. 오류 : 홀수 길이 문자열.
hamza

3
@hamza : '0'16 진수 문자열의 길이가 짝수가 아닌 경우 앞에 추가합니다 . 원래 문자열의 첫 번째 문자가 적은 16 예보다 아스키 코드가 경우가 발생 '\n'또는 '\t'. ASCII 문자에는 홀수 길이가 발생하지 않습니다 [ -~].
jfs

22

내장 전용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!

2
chr (int ()) 내가 찾던 것입니다!
JqueryToAddNumbers

내가 찾던 바로 그것!
요아킴

9

문자 별 작업 외에 어떻게 할 수 있다고 생각하는지 잘 모르겠습니다. 본질적으로 문자 별 작업입니다. 이 작업을 수행 할 수있는 코드가 분명히 있지만 문자 단위로 수행하는 것보다 "간단한"방법은 없습니다.

먼저 0b접두사 를 제거하고 문자열을 왼쪽 0으로 채워 길이가 8로 나뉘어 비트 문자열을 문자로 쉽게 나눌 수 있습니다.

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

그런 다음 문자열을 8 개의 이진수 블록으로 나누고 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)

실제로 숫자로 처리하고 싶다면 오른쪽에서 왼쪽 대신 왼쪽에서 오른쪽으로 이동하려면 맨 왼쪽 문자의 길이가 최대 7 자리라는 사실을 고려해야합니다.


2

이것이 당신의 작업을 해결하는 방법입니다.

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

str = "0"+ str [2 :]?에 '0'을 추가하는 이유는 무엇입니까? 0b는 시작이므로 여기서 제거해야합니다.
bimlesh sharma 2010 년

2

파일을 가져 오지 않으려면 다음을 사용할 수 있습니다.

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를 통해 전송하기 위해 일부 사용자 지정 암호화와 함께 사용했습니다.


1

이를 수행 할 코드를 찾고 있거나 알고리즘을 이해하고 있습니까?

이것이 당신이 필요로하는 것을합니까 ? 구체적으로 a2b_uu그리고 b2a_uu? 원하는 것이 아닌 경우 다른 옵션이 많이 있습니다.

(참고 : Python 사람은 아니지만 이것은 명백한 대답처럼 보였습니다)


나는 그것을 조금 조사해 왔고, binascii는 나를 위해 작동하지 않으며 대부분 코드를 찾고 있습니다. 볼 수 있다면 이해할 수 있습니다. 감사합니다 편집 : "h"에 대해 binascii a2b_uu를 사용하여 ascii를 바이너리로 변환하면 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00이 필요하지 않습니다 .'hello '와 실제 1과 0이 필요합니다. 또한 그것은 단지 문자로 문자를 작동, 아스키를 찾고 쉘 코드 없습니다
sbrichards

내 목적에 매우 도움이 된 @Jaxidian. 누군가 문자열에 일부 데이터를 저장했고 그것을 가지고 있습니다. 나는 그것이 패딩의 64binary b / c라고 확신합니다. 나는 그것을 성공적으로 사용할 수 b2a_base64있지만 결과는 실제로 기껏해야 혼란 스럽습니다. 거기에서 부울 / 정수 (0,1) 목록을 얻으려면 어떻게해야합니까?
Ufos

0

바이너리를 동등한 문자로 변환합니다.

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

이것은 JF Sebastian 's의 단정 한 버전입니다. 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()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.