Converter o texto binário para o 'bytearray' no Python 3
"0110100001101001"
) para uma matriz de bytes (mesmo exemplo, b"hi"
).
eu tentei isto:
bytes([int(i) for i in "0110100001101001"])
Mas eu tenho ...
b'\x00\x01\x01\x00\x01' #... and so on
Qual é a maneira correcta de fazer isto no Python 3?
3 answers
b[::-1]
.
def bitstring_to_bytes(s):
v = int(s, 2)
b = bytearray()
while v:
b.append(v & 0xff)
v >>= 8
return bytes(b[::-1])
s = "0110100001101001"
print(bitstring_to_bytes(s))
Claramente, a segunda via do Patrick é mais compacta. :)
No entanto, há uma maneira melhor de fazer isto no Python 3: use o int. to_ bytes método:
def bitstring_to_bytes(s):
return int(s, 2).to_bytes(len(s) // 8, byteorder='big')
>>> zero_one_string = "0110100001101001"
>>> int(zero_one_string, 2).to_bytes((len(zero_one_string) + 7) // 8, 'big')
b'hi'
Devolve bytes
o objecto que é uma sequência imutável de bytes. Se você quiser obter um bytearray
-- uma sequência mutável de bytes -- então basta ligar para bytearray(b'hi')
.
Você tem que convertê-lo em um int e tomar 8 bits de cada vez, ou cortá-lo em cordas de 8 bytes longos e, em seguida, converter cada um deles em ints. No Python 3, como as respostas de PM 2Ring e J. F Sebastian mostram, o método to_bytes()
de int
permite que você faça o primeiro método de forma muito eficiente. Isso não está disponível no Python 2, então para as pessoas presas com isso, o segundo método pode ser mais eficiente. Aqui está um exemplo:
>>> s = "0110100001101001"
>>> bytes(int(s[i : i + 8], 2) for i in range(0, len(s), 8))
b'hi'
Para quebrar isto, o intervalo começa em índice 0, e nos dá índices na cadeia de fonte, mas avança 8 índices de cada vez. Uma vez que s
tem 16 caracteres de comprimento, vai dar - nos dois índices:
>>> list(range(0, 50, 8))
[0, 8, 16, 24, 32, 40, 48]
>>> list(range(0, len(s), 8))
[0, 8]
(usamos list()
aqui para mostrar os valores que serão recuperados a partir do iterador de gama no Python 3.)
>>> [s[i : i + 8] for i in range(0, len(s), 8)]
['01101000', '01101001']
Então podemos converter cada um deles em inteiros, base 2:
>>> list(int(s[i : i + 8], 2) for i in range(0, len(s), 8))
[104, 105]
E finalmente ... , embrulhamos tudo em {[9] } para obter a resposta:
>>> bytes(int(s[i : i + 8], 2) for i in range(0, len(s), 8))
b'hi'