diff --git a/VERSION b/VERSION index 93571de..c5262af 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2407.311838 +0.2407.311904 diff --git a/src/IntegerBaseConverter.php b/src/IntegerBaseConverter.php new file mode 100644 index 0000000..783ed0a --- /dev/null +++ b/src/IntegerBaseConverter.php @@ -0,0 +1,100 @@ +maxBase = $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 { + 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 ''; + + $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; + } + + return $output; + } + + /** + * 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'); + } + + if($string === '') + return 0; + + $output = 0; + $length = strlen($string) - 1; + + for($i = 0; $i <= $length; ++$i) { + $pos = strpos($this->characterSet, $string[$i]); + if($pos === false) + return false; + + $output += $pos * ($fromBase ** ($length - $i)); + } + + return $output; + } +} diff --git a/src/Serialisation/Base62.php b/src/Serialisation/Base62.php deleted file mode 100644 index 92fd1e2..0000000 --- a/src/Serialisation/Base62.php +++ /dev/null @@ -1,53 +0,0 @@ -= 0; --$i) { - $index = (int)floor($integer / (self::BASE ** $i)); - $output .= substr(self::CHARS, $index, 1); - $integer -= $index * (self::BASE ** $i); - } - - return $output; - } - - /** - * Converts a base62 integer to a base10 integer. - * - * @param string $string The encoded integer. - * @return int|false Returns the decoded integer or false on failure. - */ - public static function decode(string $string): int|false { - $output = 0; - $length = strlen($string) - 1; - - for($i = 0; $i <= $length; ++$i) { - $pos = strpos(self::CHARS, $string[$i]); - if($pos === false) - return false; - - $output += $pos * (self::BASE ** ($length - $i)); - } - - return $output; - } -} diff --git a/src/XNumber.php b/src/XNumber.php index a8df0f7..c0a0f04 100644 --- a/src/XNumber.php +++ b/src/XNumber.php @@ -1,16 +1,43 @@ encode($integer); + } + + /** + * Converts a base62 integer to a base10 integer. + * + * @param string $string The encoded integer. + * @return int|false Returns the decoded integer or false on failure. + */ + public static function fromBase62(string $string): int|false { + return self::getBase62Converter()->decode($string); + } + public static function weighted(float $num1, float $num2, float $weight): float { $weight = min(1, max(0, $weight)); return ($num1 * $weight) + ($num2 * (1 - $weight)); diff --git a/tests/Base62Test.php b/tests/Base62Test.php index d03353e..1b83576 100644 --- a/tests/Base62Test.php +++ b/tests/Base62Test.php @@ -7,9 +7,9 @@ declare(strict_types=1); use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\CoversClass; -use Index\Serialisation\Base62; +use Index\XNumber; -#[CoversClass(Base62::class)] +#[CoversClass(XNumber::class)] final class Base62Test extends TestCase { public const TESTS = [ ['aaaaaa', 9311514030], @@ -25,11 +25,11 @@ final class Base62Test extends TestCase { public function testDecode(): void { foreach(self::TESTS as $test) - $this->assertEquals($test[1], Base62::decode($test[0])); + $this->assertEquals($test[1], XNumber::fromBase62($test[0])); } public function testEncode(): void { foreach(self::TESTS as $test) - $this->assertEquals($test[0], Base62::encode($test[1])); + $this->assertEquals($test[0], XNumber::toBase62($test[1])); } }