web-dev-qa-db-ja.com

バイナリをASCIIに、またはその逆に変換します

このコードを使用して文字列を取得し、バイナリに変換します。

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

この出力:

0b110100001100101011011000110110001101111

これを このサイト (右側のサイト)に入れると、helloというメッセージが返されます。私はそれがどの方法を使用するのだろうと思っています。バイナリの文字列を8に分割して、bin(ord(character))またはその他の方法で対応する値に一致させることができます。もっとシンプルなものを本当に探しています。

69
sbrichards

ASCII 2上の[ -~]の範囲の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'

Python 3ですべてのUnicode文字をサポートするには:

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
141
jfs

組み込みのみ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!
14
tmthydvnprt

私はあなたがどのように文字ごとにそれを行うことができると思うかわかりません-それは本質的に文字ごとの操作です。これを行うためのコードは確かにありますが、文字ごとに行うよりも「簡単な」方法はありません。

最初に、0bプレフィックスを削除し、文字列を左ゼロ詰めして、長さを8で割り切れるようにして、ビット文字列を簡単に文字に分割できるようにする必要があります。

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

次に、文字列を8桁の2進数のブロックに分割し、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桁になるという事実を考慮する必要があります。

9
agf

ファイルをインポートしたくない場合は、これを使用できます:

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経由で送信するためにカスタム暗号化で使用しました。

2
Kyle Burns

これがあなたの仕事を解決する私の方法です:

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

それを行うためのコードを探していますか、それともアルゴリズムを理解していますか?

これは必要なことを行いますか ?具体的にはa2b_uuおよびb2a_uu?あなたが望むものではない場合のために、そこには他のオプションがたくさんあります。

(注:Pythonの男ではありませんが、これは明らかな答えのように見えました)

1
Jaxidian