在PHP中,对64位整数的二进制值进行Base64编码不起作用。

huangapple go评论74阅读模式
英文:

base64 encoding of binary value of 64 bit integer in PHP is not working

问题

如何在PHP中使用base64编码处理64位整数的二进制字符串?

以下是代码,但它没有按预期工作:

<?php
$t=11545152599186258990;
$byte_array_t = pack('P',$t);
echo base64_encode($byte_array_t); //结果不正确 - 应该是: LrwswB6fOKA=
echo '
';
$t=11;
$byte_array_t = pack('P',$t);
echo base64_encode($byte_array_t); //正确

我正在尝试在PHP中实现下面的Go代码,所以我需要这样做:

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)
}

请注意,以上是您提供的代码和问题的翻译。

英文:

How to use base64 encoding with binary string of 64 bit integer on PHP?

This code is not working as expected

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

I am doing this because I am trying to implement the below code (golang) in PHP:

package main
import (
&quot;fmt&quot;
&quot;encoding/base64&quot;
&quot;encoding/binary&quot;
)



func main()  {

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



}

答案1

得分: 5

更新

尝试使用gmp_export替代pack。确保将整数作为字符串传递给gmp_init,否则会溢出:

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

演示

英文:

Update

Try using gmp_export instead of pack. Make sure to pass the integer as a string to gmp_init since it will overflow otherwise:

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

Demo

答案2

得分: 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; 
英文:

I suggest a tricky solution for you, divide your number into two 32Bit and Pack them.

$value = 11545152599186258990;
$highMap = 0xffffffff00000000; 
$lowMap = 0x00000000ffffffff; 
$higher = ($value &amp; $highMap) &gt;&gt;32; 
$lower = $value &amp; $lowMap; 
$packed = pack(&#39;NN&#39;, $higher, $lower); 

list($higher, $lower) = array_values(unpack(&#39;N2&#39;, $packed)); 
$originalValue = $higher &lt;&lt; 32 | $lower; 

答案3

得分: 0

首先感谢JimB的正确评论,关于你在评论中的问题,

> 有没有办法在PHP中获取11545152599186258990的二进制值?

答案是:

> PHP在内部将整数值存储为机器相关大小的有符号值(C类型长整型)。整数字面量和产生超出整数类型范围的操作将被存储为浮点数。当将这些浮点数打包为整数时,它们首先被强制转换为整数类型。这可能会或可能不会导致所需的字节模式。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

但它仍然在最大有符号整数的限制范围内。

英文:

First thanks to JimB for his right comment and Regarding your question in comments ,

> Is there any way to get the binary value of 11545152599186258990 in PHP?

The answer is :

> PHP internally stores integer values as signed values of a machine-dependent size (C type long). Integer literals and operations that yield numbers outside the bounds of the integer type will be stored as float. When packing these floats as integers, they are first cast into the integer type. This may or may not result in the desired byte pattern. http://php.net/manual/ro/function.pack.php

And the Range of inputs on 64-bit machines is

> 9223372036854775807 (largest signed integer) http://php.net/manual/en/function.decbin.php

And you can compare it with your given Number .

There is very important topic here https://wiki.php.net/rfc/pack_unpack_64bit_formats and finally here https://github.com/php/php-src/commit/63fd969300e39302b1f8c600bc24f049a0e13370

but is still within the limit of largest signed integer.

huangapple
  • 本文由 发表于 2017年9月14日 20:35:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/46219334.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定