Skip to content

Instantly share code, notes, and snippets.

@jfcherng
Last active November 23, 2018 07:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfcherng/44fe9183a657758df455da5a575bdaa8 to your computer and use it in GitHub Desktop.
Save jfcherng/44fe9183a657758df455da5a575bdaa8 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
class IntEncoder
{
/**
* @var string all unreserved chars in URI
*
* @see https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_in_a_URI
*/
const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~';
/**
* Encode the string.
*
* @param string $raw the raw integer string
*
* @return string
*/
public static function encode(string $raw): string
{
$base = (string) strlen(static::CHARS);
$encoded = '';
do {
$remainder = bcmod($raw, $base);
$encoded .= static::CHARS[$remainder];
$raw = bcdiv($raw, $base); // quotient
} while (bccomp($raw, '0') === 1);
return $encoded;
}
/**
* Decode the string.
*
* @param string $enc the encoded string
*
* @return string
*/
public static function decode(string $enc): string
{
static $weightingMap; // cache
$base = (string) strlen(static::CHARS);
// build the weighting map for the first-time use
$weightingMap = $weightingMap ?? array_combine(
str_split(static::CHARS), // keys
array_map('strval', range(0, (int) $base - 1)) // values
);
$decoded = '';
for ($i = 0; $i < strlen($enc); ++$i) {
$decoded = bcadd(
$decoded,
bcmul($weightingMap[$enc[$i]], bcpow($base, "{$i}"))
);
}
return $decoded;
}
}
$intString = '11918780727494821840';
$encoded = IntEncoder::encode($intString);
$decoded = IntEncoder::decode($encoded);
assert($decoded === $intString);
echo 'Encoded: ', $encoded, PHP_EOL;
echo '# of chars saved: ', strlen($intString) - strlen($encoded), PHP_EOL;
@jfcherng
Copy link
Author

Output:

Encoded: W7tuQpX~lnH
# of chars saved: 9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment