2017-09-14 60 views
3

如何在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

回答

1

更新

嘗試使用gmp_export而不是pack。確保傳遞整數作爲字符串gmp_init因爲它會另有溢出:

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

Demo

1

我提出一個棘手的爲您解決,將您的號碼爲兩個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; 
0

首先感謝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

但仍是最大的有符號整數的範圍內。

相關問題