【问题标题】:Reading an 8 byte integer in PHP (Bitcoin)在 PHP(比特币)中读取一个 8 字节整数
【发布时间】:2013-07-18 04:39:51
【问题描述】:

我正在尝试从比特币交易中读取价值 - 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。

【问题讨论】:

  • 您在这里使用的$data 是什么?
  • 嗯,该页面的哪一部分是二进制数据? “原始交易”仍然看起来像 JSON。
  • 您必须自己从网络上下载交易以获得完整的二进制版本,该站点仅说明格式,不分发二进制版本。为简单起见,我已将二进制转换为十六进制,将十六进制添加到我的问题中并将其转换回二进制。
  • @PeterO。我无法更改这些数字的存储方式 - 这是既定协议的一部分。

标签: php bitcoin


【解决方案1】:

正如 PHP 的 unpack() 函数的文档说明,如果您尝试解压缩长度等于 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"

【讨论】:

  • 谢谢 - 在您发布之前,我设法使用 BC Math 让它工作,但我更喜欢您的版本,因为它不需要库,而且因为我是新用户,所以我无法发布它再等 5 小时 - 接受答案。请注意:比特币夸大了它的数字,应该是 500 - 你可能想把 / 100000000 放在那里。
  • 确实如此。虽然如果您想避免舍入错误,您可能希望跳过 / 100000000 并将值存储为 Satoshis 的整数而不是 BTC 的小数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
相关资源
最近更新 更多