【问题标题】:Byte array in Python only accepts unsigned integersPython中的字节数组只接受无符号整数
【发布时间】:2018-10-13 03:21:59
【问题描述】:

我正在使用 Python 中的音频编解码器(yikes)使用字节数组来编辑音频文件中的单个字节数据。

我想到了某种加密,它要求我对存储在字节数组中的单个字节执行按位操作。

其中一个操作是~ 运算符(按位非),它实质上反转了位(b'0001 变为 b'1110)。

问题是当您引用字节数组的单个元素时,它会返回一个 int(默认情况下 Python 是否考虑无类型的 8 位数据整数?)。 Python 中的整数默认是有符号的(我认为 Python 中甚至不存在无符号整数)。

当您尝试对字节数组中的一个字节执行按位 NOT 操作时,您会收到以下错误:

>>> array[0] = ~array[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: byte must be in range(0, 256)

这是因为它需要一个介于 0-255 之间的无符号整数。如何将有符号整数转换为无符号整数,以使用于表示两个值的位保持不变?

干杯

【问题讨论】:

  • 我认为 numpy 应该提供无符号整数。我会尝试 np.array(array).astype(np.uint8)
  • “我想到了某种加密”——你是在写自己的加密吗? Please don't write your own crypto.
  • 哈哈不...我永远不会尝试那样...试图模仿其他东西

标签: python arrays binary codec


【解决方案1】:

使用不同的操作进行位翻转。

例如:1

array[i] = 255 - array[i]

也可以:

array[i] = 255 ^ array[i]

将翻转所有(即:8)位。


1这背后的数学可以从two's complement维基百科页面计算出来。

【讨论】:

  • 不会是256 - array[0] 吗?感谢快速响应。像这样的东西让我觉得自己很愚蠢嘿嘿。
  • @JonathanMay:不。如果array[0]最初是0,那么256 - array[0]256,但所需的输出是255
  • @JonathanMay:你为什么不试试看呢? for i in range(256): print('{:08b} {:08b}'.format(i, 255-i))
  • @JonathanMay:实际上:all([{'0':'1','1':'0'}[c] for c in f'{i:08b}']==list('{:08b}'.format(255-i)) for i in range(256)) == True
  • @JonathanMay:~0 给出-1,但这个答案不涉及~
【解决方案2】:

在玩了一点二进制计算器之后,解决方案实际上非常简单。

只需从 256 中减去 SIGNED int 的大小,即可得到具有相同二进制表示形式的 UNSIGNED int 的值。

所以,

-23 已签名将是 233 未签名。

希望这可以帮助其他正在寻找解决方案的人:)

编辑:对于那些说答案是255 - array[0]。在这种情况下,我正在寻找一种从 post NOT'd int 到未签名的对应部分的方法。所以我已经对整数执行了按位非运算,现在我只是将它恢复为可以输入到字节数组中的形式。

所以最后它看起来像这样:

tmp = ~array[0]
array[0] = 256 + tmp

array[0] = 256 - abs(tmp)

这让我得到了正确的答案:)

【讨论】:

  • 不是 256。255。从 256 中减去会将范围从 0-255 更改为 1-256。
  • 或者,如果您已经在使用~ 的输出,那么您需要将其添加到 256,而不是减去。
  • 如果你要一个号码,说-12。在二进制中,这是11110100。如果您随后将11110100 转换为无符号整数,您将得到244。我是不是哪里出错了?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-03
  • 2023-01-07
相关资源
最近更新 更多