[英]Convert from 8 bits array to 5 bits array
Is there easy way for python to convert from 8 bits to 5 bits. python是否有简单的方法将8位转换为5位。 Currently I am using this code to do it: 目前,我正在使用此代码执行此操作:
def convertbits(data, frombits, tobits, pad=True):
acc = 0
bits = 0
ret = []
maxv = (1 << tobits) - 1
max_acc = (1 << (frombits + tobits - 1)) - 1
for value in data:
if value < 0 or (value >> frombits):
return None
acc = ((acc << frombits) | value) & max_acc
bits += frombits
while bits >= tobits:
bits -= tobits
ret.append((acc >> bits) & maxv)
if pad:
if bits:
ret.append((acc << (tobits - bits)) & maxv)
elif bits >= frombits or ((acc << (tobits - bits)) & maxv):
return None
return ret
is there a better way? 有没有更好的办法?
Edit: output should be list of 5bit integers without loosing any data in proccess 编辑:输出应为5位整数列表,而不会丢失过程中的任何数据
it should work like: 它应该像这样工作:
>>> hello = [ord(letter) for letter in 'hello']
>>> hello
[104, 101, 108, 108, 111]
>>> convertbits(hello, 8, 5)
[13, 1, 18, 22, 24, 27, 3, 15]
>>>
Well, this is relatively memory-inefficient as it converts individual bits to strings, but it seems to work: 嗯,这是相对低效的内存,因为它将单个位转换为字符串,但似乎可以正常工作:
import itertools
def convertbits(data, From, To):
bits_orig = itertools.chain.from_iterable(bin(n)[2:].zfill(From) for n in data)
chunks = iter(lambda: ''.join(itertools.islice(bits_orig, To)), '')
return [int(n, 2) for n in chunks]
print(convertbits(b'hello', 8, 5))
print([13, 1, 18, 22, 24, 27, 3, 15])
Once you got a stream of bits of the numbers ( bits_orig
), it's then simple to slice this stream into chunks of equal length ( chunks
) (this version doesn't do padding but it's fairly simple to implement) and convert the strings of ones and zeros back to numbers. 一旦获得一串数字位( bits_orig
),就可以很容易地将此流切成等长的chunks
( chunks
)(此版本不进行填充,但实现起来相当简单)并转换成一串和零回到数字。
If you're working with 8-bit numbers exclusively, here's an algorithm that's 8.5 (!) times faster than the one above: 如果仅使用8位数字,则此算法比上述算法快8.5 (!)倍:
from collections import deque
def convert8bits(data, To):
number = int.from_bytes(data, 'big')
ret = deque()
th = (1 << To) - 1
while number:
ret.appendleft(number & th)
number >>= To
return ret
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.