2022-09-13 13:13:11 +00:00
|
|
|
<?php
|
2023-07-21 21:47:41 +00:00
|
|
|
// Base32.php
|
2022-09-13 13:13:11 +00:00
|
|
|
// Created: 2022-01-13
|
2024-07-31 18:25:01 +00:00
|
|
|
// Updated: 2024-07-31
|
2022-09-13 13:13:11 +00:00
|
|
|
|
|
|
|
namespace Index\Serialisation;
|
|
|
|
|
|
|
|
/**
|
2024-07-31 18:25:01 +00:00
|
|
|
* Provides Base32 encoding.
|
2022-09-13 13:13:11 +00:00
|
|
|
*/
|
2023-07-21 21:47:41 +00:00
|
|
|
final class Base32 {
|
2022-09-13 13:13:11 +00:00
|
|
|
private const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
|
|
|
|
|
|
|
/**
|
2024-07-31 18:25:01 +00:00
|
|
|
* Encodes data with RFC4648 base32.
|
2022-09-13 13:13:11 +00:00
|
|
|
*
|
2024-07-31 18:25:01 +00:00
|
|
|
* @param string $string The data to encode.
|
|
|
|
* @return string The encoded data, as a string.
|
2022-09-13 13:13:11 +00:00
|
|
|
*/
|
2024-07-31 18:25:01 +00:00
|
|
|
public static function encode(string $string): string {
|
|
|
|
$length = strlen($string);
|
2022-09-13 13:13:11 +00:00
|
|
|
$bin = '';
|
|
|
|
$output = '';
|
|
|
|
|
|
|
|
for($i = 0; $i < $length; $i++)
|
2024-07-31 18:25:01 +00:00
|
|
|
$bin .= sprintf('%08b', ord($string[$i]));
|
2022-09-13 13:13:11 +00:00
|
|
|
|
|
|
|
$bin = str_split($bin, 5);
|
|
|
|
$last = array_pop($bin);
|
2023-01-01 18:47:24 +00:00
|
|
|
$bin[] = str_pad((string)$last, 5, '0', STR_PAD_RIGHT);
|
2022-09-13 13:13:11 +00:00
|
|
|
|
|
|
|
foreach($bin as $part)
|
|
|
|
$output .= self::CHARS[bindec($part)];
|
|
|
|
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-07-31 18:25:01 +00:00
|
|
|
* Decodes data encoded with RFC4648 base32.
|
2022-09-13 13:13:11 +00:00
|
|
|
*
|
2024-07-31 18:25:01 +00:00
|
|
|
* @param string $string The encoded data.
|
|
|
|
* @return string|false Returns the decoded data or false on failure. The returned data may be binary.
|
2022-09-13 13:13:11 +00:00
|
|
|
*/
|
2024-07-31 18:25:01 +00:00
|
|
|
public static function decode(string $string): string|false {
|
|
|
|
$length = strlen($string);
|
2022-09-13 13:13:11 +00:00
|
|
|
$char = $shift = 0;
|
|
|
|
$output = '';
|
|
|
|
|
|
|
|
for($i = 0; $i < $length; $i++) {
|
2024-07-31 18:25:01 +00:00
|
|
|
$pos = stripos(self::CHARS, $string[$i]);
|
|
|
|
if($pos === false)
|
|
|
|
return false;
|
|
|
|
|
2022-09-13 13:13:11 +00:00
|
|
|
$char <<= 5;
|
2024-07-31 18:25:01 +00:00
|
|
|
$char += $pos;
|
2022-09-13 13:13:11 +00:00
|
|
|
$shift = ($shift + 5) % 8;
|
|
|
|
$output .= $shift < 5 ? chr(($char & (0xFF << $shift)) >> $shift) : '';
|
|
|
|
}
|
|
|
|
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
}
|