在PHP 64位整数的二进制值的base64编码不起作用

问题描述:

如何在PHP上使用64位整数的二进制字符串base64编码?在PHP 64位整数的二进制值的base64编码不起作用

此代码不能按预期工作

<?PHP 
$t=11545152599186258990; 
$byte_array_t = pack('P',$t); 
echo base64_encode($byte_array_t); //not correct result - it should be: LrwswB6fOKA= 
echo ' 
'; 
$t=11; 
$byte_array_t = pack('P',$t); 
echo base64_encode($byte_array_t); //correct 

我这样做是因为我想在PHP中实现下面的代码(golang):

package main 
import (
"fmt" 
"encoding/base64" 
"encoding/binary" 
) 



func main() { 

    dst := make([]byte, 8) 
    binary.LittleEndian.PutUint64(dst, uint64(11545152599186258990)) 
    value :=base64.URLEncoding.EncodeToString(dst) 
    fmt.Println(value) 



} 
+3

PHP没有无符号整数类型,因此'11545152599186258990'溢出了整数并默默地转换为'float(1.1545152599186E + 19)'。 – JimB

+0

谢谢。有没有办法在PHP中获得11545152599186258990的二进制值? –

+0

你是如何得到这个数字的?你可以将它打包为2个32位数字,但是它可能仍然会在代码中的其他位置转换为浮点数。我根本不知道PHP,但可能会有一些大的整数库或可以使用的东西。 – JimB

更新

尝试使用gmp_export而不是pack。确保传递整数作为字符串gmp_init因为它会另有溢出:

$t = gmp_init("11545152599186258990"); 
$byte_array_t = gmp_export($t, 8); 
echo base64_encode($byte_array_t); // LrwswB6fOKA= 

Demo

我提出一个棘手的为您解决,将您的号码为两个32位和收拾他们。

$value = 11545152599186258990; 
$highMap = 0xffffffff00000000; 
$lowMap = 0x00000000ffffffff; 
$higher = ($value & $highMap) >>32; 
$lower = $value & $lowMap; 
$packed = pack('NN', $higher, $lower); 

list($higher, $lower) = array_values(unpack('N2', $packed)); 
$originalValue = $higher << 32 | $lower; 

首先感谢JimB实现自己的权利评论和关于在评论你的问题,

有没有什么办法让二进制值11545152599186258990在PHP中?

答案是:

PHP内部存储整数值作为机器相关的尺寸(C型长)的有符号值。整数文字和产生超出整数类型边界的数字的操作将以float方式存储。当将这些浮点数作为整数打包时,它们首先被转换为整数类型。这可能会或可能不会导致所需的字节模式。 http://php.net/manual/ro/function.pack.php

和64位机的输入范围是

9223372036854775807(最大的有符号整数)http://php.net/manual/en/function.decbin.php

你还可以用你的定数进行比较。

有非常重要的话题在这里https://wiki.php.net/rfc/pack_unpack_64bit_formats终于在这里https://github.com/php/php-src/commit/63fd969300e39302b1f8c600bc24f049a0e13370

但仍是最大的有符号整数的范围内。