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


83

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

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

この出力:

0b110100001100101011011000110110001101111

これをこのサイト(右側のサイト)に入れると、メッセージがhello返ってきます。どんな方法を使っているのか気になります。バイナリの文字列を8につなぎ合わせてから、対応する値bin(ord(character))または他の方法に一致させることができることはわかっています。もっと簡単なものを本当に探しています。


1
それで、あなたの質問は、「明白なものよりも私のコードの逆を行うためのより簡潔な方法がありますか?」ですか?
トリプリー2011

1
関連:b2a_binCythonの拡張機能を使用"01"すると、中間のPython整数を作成せずに、バイト文字列から直接バイナリ文字列()を作成できます。
jfs 2013年

回答:


160

[ -~]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ですべての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'

単一ソースのPython2 / 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私はPythonの現在のバージョンでこのメソッドを試しましたが、機能しないようです。<br/> TypeError: 'str'はバッファインターフェイスをサポートしていません<br/>回答を更新しますか
hamza 2012年

3
@hamza:Python 2で動作しますyour_string.encode('ascii', 'strict')
。Python3

1
@JFSebasitian:ありがとう。ただし、その逆を試してみると、unhexlify関数がエラーメッセージを返します:binascii.Error:奇数の長さの文字列。
hamza 2012年

3
@hamza:'0'16進文字列の長さが均等でない場合は、先頭に追加します。元の文字列の最初の文字のASCIIコードが16未満の場合に発生します(例:'\n'または)'\t'。アスキー文字の場合、奇数の長さは発生しません[ -~]
jfs 2012年

25

ビルトインのみ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!

2
chr(int())は私が探していたものです!
jqueryToAddNumbers 2017年

まさに私も探していたもの!!
ヨアヒム

10

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

まず、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桁になるという事実を考慮する必要があります。


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 2013年

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"にbinasciia2b_uuを使用してASCIIをバイナリに変換するときは\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00であり、これは必要なものではありません。「hello」と実際の1と0が必要です。シェルコードのように見えるASCIIではなく、char
ごと

@Jaxidianは私の目的に非常に役立ちました。誰かがいくつかのデータを文字列に保存しましたが、私はそれを持っています。私はそれがパディングの64バイナリb / cであると確信しています。私はそれをうまく使うことができますb2a_base64、しかし結果は確かにせいぜい混乱します。そこからboolleans / integer(0,1)のリストを取得するにはどうすればよいですか?
ufos 2018

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セバスティアンのスプルースアップバージョンです。JFセバスチャンを通してスニペットをありがとう。

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.