问题
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