【问题标题】:Reassembling negative Python marshal int's into Javascript numbers将负 Python marshal int 重新组装成 Javascript 数字
【发布时间】:2014-12-21 23:28:32
【问题描述】:

我正在为一个类项目使用 Javascript(特别是 Typescript)编写客户端 Python 字节码解释器。解析字节码一直很好,直到我尝试了一个负数。

在 Python 中,marshal.dumps(2) 给出 'i\x02\x00\x00\x00'marshal.dumps(-2) 给出 'i\xfe\xff\xff\xff'。这是有道理的,因为 Python 使用至少 32 位精度的二进制补码来表示整数。

在我的 Typescript 代码中,我使用等效于 Node.js 的 Buffer 类(通过名为 BrowserFS 的库,而不是 ArrayBuffers 等)来读取数据。当我看到字符“i”(即buffer.readUInt8(offset) == 105,表示接下来是一个int)时,我在下一个偏移量上调用readInt32LE 以读取一个little-endian 有符号长(4 个字节)。这适用于正数,但不适用于负数:对于 1,我得到“1”,但对于“-1”,我得到类似“-272777233”的东西。

我猜 Javascript 表示 64 位的数字(浮点数?)。因此,似乎以下应该可以工作:

var longval = buffer.readInt32LE(offset); // reads a 4-byte long, gives -272777233 
var low32Bits = longval & 0xffff0000; //take the little endian 'most significant' 32 bits
var newval = ~low32Bits + 1; //invert the bits and add 1 to negate the original value
//but now newval = 272826368 instead of -2

我尝试了很多不同的方法,但我已经坚持了好几天。我不知道如何使用 Javascript/Typescript 从二进制编组字符串中恢复 Python 整数的原始值。此外,我认为我深深误解了位的工作原理。任何想法都会在这里受到赞赏。

一些更具体的问题可能是:

  • 为什么buffer.readInt32LE 可以用于正整数而不是负整数?
  • 我是否使用正确的方法来获取“最重要”或“最低”的 32 位(即 & 0xffff0000 是否按照我的想法工作?)
  • 独立但相关:在一个实际的“长”数字中(即比“-2”长),我认为有一个符号位和一个幅度,我认为这个信息存储在“最高”2位数字(即number & 0x000000ff?)——这是正确的思考方式吗?

【问题讨论】:

  • BrowserFS 代码的真正简化版本适用于负值。您可以发布四次调用readUInt8 的输出以验证您正在阅读预期的序列FE FF FF FF 吗?
  • 这是问题的很大一部分——我没有得到预期的序列。相反,对于 -2 我得到: ef bf bd ef
  • 似乎您只是在读取流的错误部分,或者 Python 没有使用您认为的数字格式。我认为没有任何合理的按位运算序列可以将EF BF BD EF 变成-2
  • 问题是,我正在使用 a = 2, b = -2 的编译字节码进行测试,以此类推几个数字。正数是正确的,以及整个“代码对象”结构。唯一不正确的是负数值。所以我不知道如何在不搞乱其他所有内容的情况下更改我在流中阅读的位置。

标签: javascript python typescript bit-manipulation number-formatting


【解决方案1】:

序列ef bf bdis the UTF-8 sequence for the "Unicode replacement character",Unicode 编码器用来表示无效编码。

听起来您用于下载数据的任何方法都意外地通过了 UTF-8 解码器并损坏了原始数据流。确保您使用的是blob 而不是text,或者任何与您下载字节码的方式相同的东西。

这只是对负值造成混乱,因为正值在 UTF-8 的法线映射空间内,因此从原始字节流中按 1:1 进行转换。

【讨论】:

  • 哇,我绝对应该先检查一下,在上面的繁琐之前。谢谢。
  • 如果你碰巧在 GitHub 或其他地方发布了你的代码,你能在这里发表评论吗?我是 TypeScript 团队的一员,我们一直在寻找更大/有趣的代码库以用于分析和回归测试。
  • 我会问我的教授是否可以将存储库公开并让您知道
猜你喜欢
  • 1970-01-01
  • 2018-10-15
  • 2016-01-11
  • 2017-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
相关资源
最近更新 更多