2010-09-12 46 views
1

我已经使用解包来转换大多数数据类型,我有一个二进制文件,我解析一些小问题。我不知道如何处理一个大的64位长签名。我认为这个数据类型是用2的补码存储的。我正在阅读的数据文件的应用程序是一个Java应用程序,所以我认为它是2的补充。我不需要将它作为一个数字来处理,而只是将它作为一个字符串来处理。如何将二进制文件中的64位Java解析为PHP字符串?

回答

0

Java 64位整数确实存储为“网络顺序”(大端,即以最高有效字节开始)的8字节2的补码格式。因此,通常你每次都要采用字节,向左移8,重复。字节值可以认为是无符号的(虽然结果是有符号的),但是左移这并不重要。因此:首先,您只是从字节创建了等效的64位int,然后从那里显示。没有意义使用捷径;尽管这是可能的,但最终只会出现更复杂,效率更低的代码。

+0

我想我忘了提,我正在使用的PHP是32位的。我想我需要尝试与BCMath图书馆或一些这样的工作? – fadeddata 2010-09-12 15:25:44

+0

在这种情况下,我认为32位不重要,它不应该影响“较大”数据类型的存在(而是与寻址等有关)。但我有点PHP新手,所以我希望其他人可以证实这一点。 – StaxMan 2010-09-13 02:27:11

+0

PHP的整数大小取决于平台。一个32位操作系统将只有一个32位有符号整数。任何溢出的东西都会被转换为浮动。 – Matthew 2010-11-21 02:31:55

0

32位PHP将只有32位整数签名,据我所知,没有办法本地解包数据。

下面的代码应该能够读取大端,补64位整数:

<?php 
function read_int64($fp) 
{ 
    $hex = unpack('H16a', fread($fp, 8)); 
    $hex = '0x'.$hex['a']; 

    $n = gmp_init($hex); 

    if (gmp_testbit($n, 63)) 
    { 
    $n = gmp_xor($n, '0xffffffffffffffff'); // flip the bits 
    $n = gmp_neg(gmp_add($n, 1));   // add one and negate 
    } 

    return gmp_strval($n); 
} 
?> 

它返回整数为字符串。它可用于像:

$fp = fopen('test.bin', 'rb'); 
echo read_int64($fp)."\n"; 
fclose($fp); 

(编辑:更新的代码来调用较少的GMP功能。)

相关问题