Open EthraZa opened 8 years ago
You are using PHP 5.3 which was released in 2009 and where support ended for in 2014.
Short array syntax ([]
instead of array()
) was introduced in PHP 5.4.
This package requires PHP >= 5.4 if you have a look at the composer.json file.
Anyway, support for PHP 5.4 ended in 2015, and 5.5 was actually supported until yesterday, so I'd recommend you to upgrade to 5.6 if you can.
Yes I noticed the sintaxe, because of that I have to change line 108. So are you saying that even changing this line and it seeming as it's working, it will not work properly because of the PHP version?
I'm not the author of this package, but as it requires PHP >= 5.4 you may experience unexpected behavior with a lower version. What you can do is to run the tests and check if they pass.
Optimus only works if the id is less than max int. it is designed that way. If you want, you can fork the library and increase MAX_INT not 9223372036854775807. https://github.com/jenssegers/optimus/issues/17
We could add a method to override the internal max integer value.
@jenssegers @pjebs i did try to increase MAX_INT in Optimus.php but it doesn't work
#uname -a
Linux web2 2.6.32-573.8.1.el6.x86_64 #1 SMP Tue Nov 10 18:01:38 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
...
const MAX_INT = 100000000000; //12 digits
...
$ob = new Jenssegers\Optimus\Optimus(615006283, 1261799779, 332484960);
$id = "10000000000"; //11 digits
$encoded = $ob->encode($id);
$original = $ob->decode($encoded);
print_r(array($id, $encoded, $original));
Result:
Array
(
[0] => 10000000000
[1] => 30528477536
[2] => 73155108864
)
are you sure const MAX_INT = 100000000000; //12 digits
is within the class. I thikn jensegers added a method to override the default in new version.
@pjebs I'm very sure. I also checked over the source but no method to override default MAX_INT. I saw your comments on repo optimus-go, it seems very easy to change, but i have no idea why it doesn't work on my test. Thank you!
v0.2.2
php -v
PHP 5.6.30 (cli) (built: Jan 19 2017 10:06:11)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
...
<?php namespace Jenssegers\Optimus;
use InvalidArgumentException;
class Optimus
{
/**
* @var int
*/
const MAX_INT = 100000000000;
/**
* @var string
*/
private static $mode;
/**
* Use GMP extension functions.
*/
const MODE_GMP = 'gmp';
/**
* Use native PHP implementation.
*/
const MODE_NATIVE = 'native';
/**
* @var int
*/
private $prime;
/**
* @var int
*/
private $inverse;
/**
* @var int
*/
private $xor;
/**
* @param int $prime
* @param int $xor
* @param int $inverse
*/
public function __construct($prime, $inverse, $xor = 0)
{
$this->prime = (int) $prime;
$this->inverse = (int) $inverse;
$this->xor = (int) $xor;
// Check which calculation mode should be used.
if (static::$mode === null) {
static::$mode = PHP_INT_SIZE === 4 ? static::MODE_GMP : static::MODE_NATIVE;
}
}
/**
* Encode an integer.
*
* @param int $value
* @return int
*/
public function encode($value)
{
if (! is_numeric($value)) {
throw new InvalidArgumentException('Argument should be an integer');
}
switch (static::$mode) {
case self::MODE_GMP:
return (gmp_intval(gmp_mul($value, $this->prime)) & static::MAX_INT) ^ $this->xor;
default:
return (((int) $value * $this->prime) & static::MAX_INT) ^ $this->xor;
}
}
/**
* Decode an integer.
*
* @param int $value
* @return int
*/
public function decode($value)
{
if (! is_numeric($value)) {
throw new InvalidArgumentException('Argument should be an integer');
}
switch (static::$mode) {
case static::MODE_GMP:
return gmp_intval(gmp_mul((int) $value ^ $this->xor, $this->inverse)) & static::MAX_INT;
default:
return (((int) $value ^ $this->xor) * $this->inverse) & static::MAX_INT;
}
}
/**
* Set the internal calculation mode (mainly used for testing).
*
* @param string $mode
*/
public function setMode($mode)
{
if (! in_array($mode, [static::MODE_GMP, static::MODE_NATIVE])) {
throw new InvalidArgumentException('Unkown mode: ' . $mode);
}
static::$mode = $mode;
}
}
Try essentially creating your own Optimus class that is exactly
the same as the official one and then a) test if your test works and b) if your changed MAX_INT
is reflected inside the class
hi @pjebs i forked this repo, change MAX_INT,.. and made a test https://github.com/tamhv/optimus/blob/master/tests/CustomTest.php
// const MAX_INT = 1000000000000;//13 digits
//
// var_dump(\Jenssegers\Optimus\Energon::generatePrime());//204370143667
// ./optimus spark 204370143667
// Prime: 204370143667
// Inverse: 676326779
// Random: 1054205207
//
// new Optimus(204370143667, 676326779, 1054205207);
$ob = new Optimus(204370143667, 676326779, 1054205207);
$id = 10000000000; //11 digits
$encoded = $ob->encode($id);
$original = $ob->decode($encoded);
print_r([$id, $encoded, $original]);
// Array
// (
// [0] => 10000000000
// [1] => 722264515863
// [2] => 446746066944
// )
// encode?
// (((int) $value * $this->prime) & static::MAX_INT) ^ $this->xor;
// (((int) 10000000000 * 204370143667) & 1000000000000) ^ 1054205207; //722264515863
//
// decode?
// (((int) $value ^ $this->xor) * $this->inverse) & static::MAX_INT;
// (((int) 722264515863 ^ 1054205207) * 676326779) & 1000000000000; //446746066944
It still doesn't work, can you please have a look and correct me if anything wrong. Thank you in advance.
Can you try the example values in the ReadMe. See if you can recreate those results.
I suspect const MAX_INT = 1000000000000;//13 digits
can't just be any number. I think it has to be a power of 2 (not documented).
it doesn't match (PRIME * INVERSE) & MAXID == 1
, so there is some thing wrong with optimus spark
. It gave me wrong PRIME and INVERSE if MAX_INT greater than 2147483647.
I did try with MAX_INT=8589934593
and ((366693263 * 620196719) & 8589934593) == 1
but still not work:
$ob = new Optimus(366693263, 620196719, 1066048704);
$id = 5; //11 digits
$encoded = $ob->encode($id);
$original = $ob->decode($encoded);
print_r([$id, $encoded, $original]);
Array
(
[0] => 5
[1] => 1066048705
[2] => 1
)
@tamhv, @pjebs take a look at #29 – that should help.
It seems the max number can only be 2147483647? even 64bit system with PHP 7.1 I'm not sure this issue is from this package code or the limitation of hashing algorithm used.
Installed optimus package and used the below code
$optimus = new Optimus(158003, 59260, 1163);
$value = "10000"; $encoded = $optimus->encode($value); $original = $optimus->decode($encoded); print_r(array($value, $encoded, $original), true);
i am getting this error :: Call to undefined function Jenssegers\Optimus\gmp_intval()
you prob need gmt php extension installed
Hi. Using the example numbers:
My IDs are MySQL's bigint that can be 20 digits long! Optimus is not for me? What am I missing? There is a length limit?
php -v PHP 5.3.2-1ubuntu4.30 with Suhosin-Patch (cli) (built: Apr 17 2015 15:01:29) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
uname -a Linux picard 2.6.32-74-server #142-Ubuntu SMP Tue Apr 28 10:12:19 UTC 2015 x86_64 GNU/Linux
I had to change line 108 at src/Optimus.php to get it working:
to
Thanks in advance.