23

ASCII 文字列をビットのリストに、またはその逆に変換する必要があります。

str = "Hi" -> [0,1,0,0,1,0,0,0,0,1,1,0,1,0,0,1]

[0,1,0,0,1,0,0,0,0,1,1,0,1,0,0,1] -> "Hi"
4

11 に答える 11

39

ライブラリ関数でこれを行う方法はたくさんあります。しかし、私はサードパーティのbitarrayモジュールに部分的です。

>>> import bitarray
>>> ba = bitarray.bitarray()

文字列からの変換には、ちょっとした儀式が必要です。むかしむかし、単に を使用できましたfromstringが、文字列を暗黙的にバイトにエンコードする必要があるため、そのメソッドは現在非推奨です。避けられないエンコード エラーを回避するには、bytesオブジェクトをに渡すことをお勧めしますfrombytes。文字列から開始する場合、エンコーディングを明示的に指定する必要があることを意味します。これはとにかく良い習慣です。

>>> ba.frombytes('Hi'.encode('utf-8'))
>>> ba
bitarray('0100100001101001')

リストへの変換は簡単です。(また、ビット文字列オブジェクトにはすでに多くのリストのような関数があります。)

>>> l = ba.tolist()
>>> l
[False, True, False, False, True, False, False, False, 
 False, True, True, False, True, False, False, True]

bitstrings は、任意の iterable から作成できます。

>>> bitarray.bitarray(l)
bitarray('0100100001101001')

バイトまたは文字列への変換も比較的簡単です。

>>> bitarray.bitarray(l).tobytes().decode('utf-8')
'Hi'

そして純粋な娯楽のために:

>>> def s_to_bitlist(s):
...     ords = (ord(c) for c in s)
...     shifts = (7, 6, 5, 4, 3, 2, 1, 0)
...     return [(o >> shift) & 1 for o in ords for shift in shifts]
... 
>>> def bitlist_to_chars(bl):
...     bi = iter(bl)
...     bytes = zip(*(bi,) * 8)
...     shifts = (7, 6, 5, 4, 3, 2, 1, 0)
...     for byte in bytes:
...         yield chr(sum(bit << s for bit, s in zip(byte, shifts)))
... 
>>> def bitlist_to_s(bl):
...     return ''.join(bitlist_to_chars(bl))
... 
>>> s_to_bitlist('Hi')
[0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1]
>>> bitlist_to_s(s_to_bitlist('Hi'))
'Hi'
于 2012-04-19T23:06:19.663 に答える
31

これを行うにはおそらくより高速な方法がありますが、追加のモジュールを使用しません。

def tobits(s):
    result = []
    for c in s:
        bits = bin(ord(c))[2:]
        bits = '00000000'[len(bits):] + bits
        result.extend([int(b) for b in bits])
    return result

def frombits(bits):
    chars = []
    for b in range(len(bits) / 8):
        byte = bits[b*8:(b+1)*8]
        chars.append(chr(int(''.join([str(bit) for bit in byte]), 2)))
    return ''.join(chars)
于 2012-04-19T23:10:55.023 に答える
9

理由はわかりませんが、ビルトインのみを使用した2つの醜いワンライナーを次に示します。

s = "Hi"
l = map(int, ''.join([bin(ord(i)).lstrip('0b').rjust(8,'0') for i in s]))
s = "".join(chr(int("".join(map(str,l[i:i+8])),2)) for i in range(0,len(l),8))

収量:

>>> l
[0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1]
>>> s
'Hi'

実際のコードでは、structまたはbitarrayモジュールを使用します。

于 2012-04-19T23:16:00.343 に答える
5

組み込みを使用できますbytearray

>>> for i in bytearray('Hi', 'ascii'):
...     print(i)
... 
72
105

>>> bytearray([72, 105]).decode('ascii')
'Hi'

そしてbin()、バイナリに変換します。

于 2012-04-19T22:56:18.797 に答える
4
def text_to_bits(text):
    """
    >>> text_to_bits("Hi")
    [0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1]
    """
    bits = bin(int.from_bytes(text.encode(), 'big'))[2:]
    return list(map(int, bits.zfill(8 * ((len(bits) + 7) // 8))))

def text_from_bits(bits):
    """
    >>> text_from_bits([0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1])
    'Hi'
    """
    n = int(''.join(map(str, bits)), 2)
    return n.to_bytes((n.bit_length() + 7) // 8, 'big').decode()

バイナリを ASCII に、またはその逆に変換する (Python) も参照してください。

于 2015-01-27T09:34:30.020 に答える