2017-09-14 1 views
3

Comment utiliser le codage base64 avec une chaîne binaire de 64 bits entiers sur PHP?L'encodage base64 de la valeur binaire d'un entier de 64 bits en PHP ne fonctionne pas

Ce code ne fonctionne pas comme prévu

<?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 

Je fais cela parce que je suis en train de mettre en œuvre le code ci-dessous (de golang) en PHP:

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 n'a pas de type entier non signé, donc '11545152599186258990' déborde l'entier et est converti silencieusement en' float (1.1545152599186E + 19) '. – JimB

+0

Merci. Est-il possible d'obtenir la valeur binaire de 11545152599186258990 en PHP? –

+0

Comment obtenez-vous le numéro en premier lieu?Vous pouvez l'emballer comme 2 nombres de 32bit, mais alors il est susceptible d'être encore converti en flotteur dans d'autres endroits dans le code. Je ne connais pas du tout le PHP, mais il peut y avoir une grande bibliothèque de nombres entiers ou quelque chose avec lequel vous pouvez travailler. – JimB

Répondre

1

Mise à jour

Essayez d'utiliser gmp_export au lieu de pack. Assurez-vous de passer l'entier comme une chaîne à gmp_init car il débordera autrement:

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

Demo

1

Je propose une solution délicate pour vous, diviser votre numéro en deux 32Bit et les emballer.

$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

Première grâce à JimB pour son droit commentaire et En ce qui concerne votre question dans les commentaires,

Est-il possible d'obtenir la valeur binaire de 11545152599186258990 en PHP?

La réponse est:

PHP stocke à l'intérieur des valeurs entières signées en tant que valeurs d'une taille dépendant de la machine (de type C de long). Les littéraux entiers et les opérations qui génèrent des nombres en dehors des limites du type entier seront stockés en tant que float. Lorsque vous placez ces flottants sous forme d'entiers, ils sont d'abord transtypés dans le type entier. Cela peut ou non entraîner le motif d'octets souhaité. http://php.net/manual/ro/function.pack.php

et la gamme d'entrées sur les machines 64 bits est

9223372036854775807 (grand entier signé) http://php.net/manual/en/function.decbin.php

Et vous pouvez le comparer avec votre numéro donné.

Il est sujet très important ici https://wiki.php.net/rfc/pack_unpack_64bit_formats et enfin ici https://github.com/php/php-src/commit/63fd969300e39302b1f8c600bc24f049a0e13370

mais il est toujours dans la limite de nombre entier le plus grand signé.