在 Python 3.x 中转换 8 位和 7 位值

问题描述

我正在尝试将无符号整数值转换为表示为 4 个 7 位字节的值;目标是使用 Roland 的地址映射 MIDI 系统独占协议发送数据,该协议表示地址和大小值,如下所示:

MSB                                    LSB
---------    ---------    ---------    ---------
0aaa aaaa    0bbb bbbb    0ccc cccc    0ddd dddd

不幸的是,我真的不知道从哪里开始这样做;目标是在 Python 3.x 中完成此操作,我目前正在对其进行原型设计。我真正遇到的问题是数学和位操作,但奇怪的是,我什至找不到任何通用算法或经验法则来执行此操作。我发现的最接近的是 documentation 大约十年前的 Perl 解决方案,但我在破译 Perl 时也遇到了一些麻烦。除此之外,我只看到了几个 C++ 问题,其答案建议使用 bitset。

对于特定的使用示例,假设我想发送 128 字节的数据。这要求我仅使用每个字节的低 7 位发送 4 字节大小的值。但是,该值通常为 0x00000080,其中 LSB 的高位为 1,需要转换。

对不起,如果这令人困惑,我可能在这里离基地很远,但有人能指出我正确的方向吗?我敢肯定以前有人这样做过,因为它似乎会在 MIDI 编程中经常出现。

解决方法

可变长度数量(如链接问题中所示)使用不同的编码。

无论如何,要将值拆分为 7 位字节,请在每一步中提取最低 7 位,然后将剩余值右移 7 位,以便下一部分在下一步中处于正确位置:

def encode_as_4x7(value):
    result = []
    for i in range(4):
        result = [value & 0x7f] + result
        value >>= 7
    return result