Created
August 5, 2019 13:07
-
-
Save joelharkes/82ac4eb0fd8226649a6118562e3817c4 to your computer and use it in GitHub Desktop.
Crockford base 32 implementation (lower case version)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Crockford base32 encoding implementation (useable with random_bytes()) | |
* see: https://www.crockford.com/base32.html. | |
*/ | |
class CrockfordBase32 | |
{ | |
const BITS_5_RIGHT = 31; | |
const CHARS = '0123456789abcdefghjkmnpqrstvwxyz'; // lower-case | |
public function sanitize(string $input) | |
{ | |
$lower = strtolower($input); | |
$cleaning = preg_replace('/o/', '0', $lower); | |
$cleaning = preg_replace('/[il]/', '1', $cleaning); | |
return preg_replace('/[^' . self::CHARS . ']/', '', $cleaning); | |
} | |
public function encode($data, $padRight = false) | |
{ | |
$dataSize = strlen($data); | |
$res = ''; | |
$remainder = 0; | |
$remainderSize = 0; | |
for ($i = 0; $i < $dataSize; ++$i) { | |
$b = ord($data[$i]); | |
$remainder = ($remainder << 8) | $b; | |
$remainderSize += 8; | |
while ($remainderSize > 4) { | |
$remainderSize -= 5; | |
$c = $remainder & (self::BITS_5_RIGHT << $remainderSize); | |
$c >>= $remainderSize; | |
$res .= static::CHARS[$c]; | |
} | |
} | |
if ($remainderSize > 0) { | |
// remainderSize < 5: | |
$remainder <<= (5 - $remainderSize); | |
$c = $remainder & self::BITS_5_RIGHT; | |
$res .= static::CHARS[$c]; | |
} | |
if ($padRight) { | |
$padSize = (8 - ceil(($dataSize % 5) * 8 / 5)) % 8; | |
$res .= str_repeat('=', $padSize); | |
} | |
return $res; | |
} | |
public function decode($data) | |
{ | |
$data = rtrim($data, "=\x20\t\n\r\0\x0B"); | |
$dataSize = strlen($data); | |
$buf = 0; | |
$bufSize = 0; | |
$res = ''; | |
$charMap = array_flip(str_split(static::CHARS)); // char=>value map | |
$charMap += array_flip(str_split(strtoupper(static::CHARS))); // add upper-case alternatives | |
for ($i = 0; $i < $dataSize; ++$i) { | |
$c = $data[$i]; | |
$b = $charMap[$c]; | |
$buf = ($buf << 5) | $b; | |
$bufSize += 5; | |
if ($bufSize > 7) { | |
$bufSize -= 8; | |
$b = ($buf & (0xff << $bufSize)) >> $bufSize; | |
$res .= chr($b); | |
} | |
} | |
return $res; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$encoder = new CrockfordBase32(); | |
$eightCharCode = $encoder->encode(random_bytes(5)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I see.
Thanks for the answer!