3

我正在尝试从比特币交易中读取价值 - https://en.bitcoin.it/wiki/Transaction

wiki 说它是一个 8 字节整数,但我没有尝试使用 unpack 给我正确的值作为小数。

除了输出的值之外,我已经能够从事务中读取其他所有内容 - 鉴于我设法解析所有与正确值对齐的其他字段,我似乎正在读取正确的 8 个字节。

和:

$bin = hex2bin('00743ba40b000000');
$value = unpack('lvalue', $bin);
// 'value' => int -1539607552

$bin = hex2bin('d67e690000000000');
$value = unpack('lvalue', $bin);
// 'value' => int 6913750

那应该是 500 和 0.0691375。

4

1 回答 1

2

作为 PHPunpack()函数的文档说明,如果您尝试解压缩长度等于 PHP 的本机整数大小(即 32 位或 64 位,具体取决于您的 PHP 的编译方式)的无符号值,可能会发生奇怪的事情:

“请注意,PHP 内部将整数值存储为带符号的。如果您解压缩一个大的无符号长整数,并且它与 PHP 内部存储的值大小相同,即使指定了无符号解包,结果也会是负数。”

可以说,这是一个 PHP 错误:如果我要求一个无符号值,我该死的希望得到一个无符号值,即使它必须在内部表示为一个浮点数。

在任何情况下,解决这个“怪癖”的一种方法是将二进制字符串解压缩成较小的块,例如每个 8 位或 16 位,然后手动重新组合它们,如下所示:

$bin = pack( 'H*', '00743ba40b000000' );

$words = array_reverse( unpack( 'v*', $bin ) );
$n = 0;
foreach ( $words as $word ) {
    $n = (1 << 16) * $n + $word;
}

echo "$n\n";  // prints "50000000000"
于 2013-07-17T20:39:51.950 回答