From 004156712b7669a228d6d9bc688f53c4cc69fa13 Mon Sep 17 00:00:00 2001 From: flashwave Date: Sun, 22 Dec 2024 02:02:53 +0000 Subject: [PATCH] Rewrote Base62 algorithm to avoid errors with very big numbers. --- VERSION | 2 +- src/IntegerBaseConverter.php | 48 ++++++++++-------------------------- tests/Base62Test.php | 6 +++-- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/VERSION b/VERSION index 231699d..8617fda 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2410.630140 +0.2410.830201 diff --git a/src/IntegerBaseConverter.php b/src/IntegerBaseConverter.php index a15528c..cc06c0d 100644 --- a/src/IntegerBaseConverter.php +++ b/src/IntegerBaseConverter.php @@ -1,7 +1,7 @@ maxBase = $length; + $this->base = $length; } /** * Converts a positive base10 integer to another base. * * @param int $integer The integer to encode. - * @param int $toBase Target base, 0 for the base of the provided character set. * @return string The encoded data, as a string. */ - public function encode(int $integer, int $toBase = 0): string { + public function encode(int $integer): string { if($integer < 0) throw new InvalidArgumentException('$integer contains a negative value, which cannot be represented'); - if($toBase === 0) - $toBase = $this->maxBase; - else { - if($toBase < 2) - throw new InvalidArgumentException('lowest supported value for $toBase is 2'); - if($toBase > $this->maxBase) - throw new InvalidArgumentException('specified $toBase value is greater than the amount of characters in the provided character set'); - } - if($integer === 0) - return ''; + return $this->characterSet[0]; $output = ''; - for($i = floor(log10($integer) / log10($toBase)); $i >= 0; --$i) { - $exp = $toBase ** $i; - $index = (int)floor($integer / $exp); - $output .= $this->characterSet[$index]; - $integer -= $index * $exp; + while($integer > 0) { + $remainder = $integer % $this->base; + $output = $this->characterSet[$remainder] . $output; + $integer = intdiv($integer, $this->base); } return $output; @@ -68,33 +57,22 @@ class IntegerBaseConverter { * Converts another base encoded integer to a base10 integer. * * @param string $string The encoded integer. - * @param int $fromBase Source base, 0 for the base of the provided character set. * @return int|false Returns the decoded integer or false on failure. */ - public function decode(string $string, int $fromBase = 0): int|false { - if($fromBase === 0) - $fromBase = $this->maxBase; - else { - if($fromBase < 2) - throw new InvalidArgumentException('lowest supported value for $fromBase is 2'); - if($fromBase > $this->maxBase) - throw new InvalidArgumentException('specified $fromBase value is greater than the amount of characters in the provided character set'); - } - + public function decode(string $string): int|false { if($string === '') return 0; $output = 0; - $length = strlen($string) - 1; - for($i = 0; $i <= $length; ++$i) { + for($i = 0; $i < strlen($string); ++$i) { $pos = strpos($this->characterSet, $string[$i]); if($pos === false) return false; - $output += $pos * ($fromBase ** ($length - $i)); + $output = $output * $this->base + $pos; } - return (int)$output; + return $output; } } diff --git a/tests/Base62Test.php b/tests/Base62Test.php index 1b83576..bd9037c 100644 --- a/tests/Base62Test.php +++ b/tests/Base62Test.php @@ -1,7 +1,7 @@ assertEquals(0, XNumber::fromBase62('')); foreach(self::TESTS as $test) $this->assertEquals($test[1], XNumber::fromBase62($test[0])); }