Reading an 8 byte integer in PHP (Bitcoin)

こ雲淡風輕ζ 提交于 2019-12-11 02:53:23

问题


I am trying to read the value from a Bitcoin transaction - https://en.bitcoin.it/wiki/Transaction

The wiki says it is an 8 byte integer, but nothing I have tried with unpack gives me the right value as a decimal.

I've been able to read everything else from the transaction except the values out the output - given the other fields I have managed to parse all line up with the correct values it appears I am reading the correct 8 bytes.

With:

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

and

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

That should be 500 and 0.0691375.


回答1:


As the documentation for PHP's unpack() function notes, strange things may happen if you try to unpack an unsigned value with length equal to PHP's native integer size (i.e. 32 or 64 bits depending on how your PHP was compiled):

"Note that PHP internally stores integral values as signed. If you unpack a large unsigned long and it is of the same size as PHP internally stored values the result will be a negative number even though unsigned unpacking was specified."

Arguably, this is a PHP bug: if I ask for an unsigned value, I damn well expect to get an unsigned value, even if it has to be internally represented as a float.

In any case, one way to work around this "quirk" is to unpack the binary string in smaller chunks of, say, 8 or 16 bits each, and reassemble them manually, like this:

$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"


来源:https://stackoverflow.com/questions/17708321/reading-an-8-byte-integer-in-php-bitcoin

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!