Here is my modified version of Verhoeff.
Code: Select all
<?php
/*/
* --¥--=====----- -----=====---------- -----=====---------------
* |
* | Verhoeff
* | ¯¯¯¯¯¯¯¯¯¯¯¯
* |
* » × Written by Kai Sellgren.
* » × These notes must stay here intact.
* |
* --¥--=====----- -----=====---------- -----=====---------------
/*/
class verhoeff
{
private $d = array(array(0,1,2,3,4,5,6,7,8,9),
array(1,2,3,4,0,6,7,8,9,5),
array(2,3,4,0,1,7,8,9,5,6),
array(3,4,0,1,2,8,9,5,6,7),
array(4,0,1,2,3,9,5,6,7,8),
array(5,9,8,7,6,0,4,3,2,1),
array(6,5,9,8,7,1,0,4,3,2),
array(7,6,5,9,8,2,1,0,4,3),
array(8,7,6,5,9,3,2,1,0,4),
array(9,8,7,6,5,4,3,2,1,0));
private $p = array(array(0,1,2,3,4,5,6,7,8,9),
array(1,5,7,6,2,8,3,0,9,4),
array(5,8,0,3,7,9,6,1,4,2),
array(8,9,1,6,0,4,3,5,2,7),
array(9,4,5,3,1,2,6,8,7,0),
array(4,2,8,6,5,7,3,9,0,1),
array(2,7,9,3,8,0,6,4,1,5),
array(7,0,4,6,9,1,3,2,5,8));
private $inv = array(0,4,3,2,1,5,6,7,8,9);
public function calculate($int,$iterations = 1,$loop = false)
{
for ($a = 0,$n = strrev($int),$b = strlen($n),$c = 0,$d = 0;$a < $b;$a++)
$c = $this -> d[$c][$this -> p[($a+1) % 8][$n[$a]]];
$d = $this -> inv[$c];
while (--$iterations)
$d .= $this -> calculate($int.$d,1,true);
return ($loop ? '' : $int).$d;
}
public function check($int,$iterations = 1,$loop = false)
{
for ($a = 0,$n = strrev($int),$b = strlen($n),$c = 0,$d = 0,$e = $iterations;$a < $b;$a++)
$c = $this -> d[$c][$this -> p[$a % 8][$n[$a]]];
if ($c != 0)
return false;
while (--$iterations)
{
if ($this -> check(substr($int,0,strlen($int)-$iterations),1,true) === false)
return false;
}
return $loop ? true : substr($int,0,strlen($int)-$e);
}
}
?>
It accepts a parameter $iterations and will return the correct value instead of boolean "true". Note, if the correct value is 0, e.g. if you check whether 04 is correct, then it returns 0 so you must do the check like this:
Note that there are two equal signs.
More over, my implementation seems faster. In the below examples, my implementation is verhoeff and yours is verhoeff2.
My implementation initializes 60 times faster.
My implementation calculates single iterations 1.26 times faster. With 100 iterations, the results were:
Which makes my implementation 1.7 times faster on a higher iteration count.
Then I tried the "check" method against "1337542174997737309409585646347774933584845524277550726944602127053306892533169692847127657489822187309". First I tried one iteration:
My implementation was 1.07 times faster. Then I tried the same value with 100 iterations and they both returned 1337 like they should have.
The difference was the performance, again. Mine was roughly 1.33 times faster.
Both implementations work, but I aimed for better performance.