index/src/Serialisation/Base32.php

63 lines
1.6 KiB
PHP
Raw Normal View History

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
2023-07-21 21:47:41 +00:00
// Updated: 2023-07-21
2022-09-13 13:13:11 +00:00
namespace Index\Serialisation;
use Index\IO\Stream;
/**
* Provides a Base32 serialiser.
*/
2023-07-21 21:47:41 +00:00
final class Base32 {
2022-09-13 13:13:11 +00:00
private const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
/**
* Encodes binary data as a Base32 string.
*
2023-07-21 21:47:41 +00:00
* @param Stream|string $input Input binary data.
2022-09-13 13:13:11 +00:00
* @return string Base32 string representing the binary data.
*/
2023-07-21 21:47:41 +00:00
public static function encode(Stream|string $input): string {
2022-09-13 13:13:11 +00:00
$input = (string)$input;
$length = strlen($input);
$bin = '';
$output = '';
for($i = 0; $i < $length; $i++)
$bin .= sprintf('%08b', ord($input[$i]));
$bin = str_split($bin, 5);
$last = array_pop($bin);
$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;
}
/**
* Decodes a Base32 string back to binary data.
*
* @param Stream|string $input Input Base32 string.
* @return string Binary data.
*/
2023-07-21 21:47:41 +00:00
public static function decode(Stream|string $input): string {
2022-09-13 13:13:11 +00:00
$input = (string)$input;
$length = strlen($input);
$char = $shift = 0;
$output = '';
for($i = 0; $i < $length; $i++) {
$char <<= 5;
$char += stripos(self::CHARS, $input[$i]);
$shift = ($shift + 5) % 8;
$output .= $shift < 5 ? chr(($char & (0xFF << $shift)) >> $shift) : '';
}
return $output;
}
}