63 lines
1.6 KiB
PHP
63 lines
1.6 KiB
PHP
|
<?php
|
||
|
// Base32Serialiser.php
|
||
|
// Created: 2022-01-13
|
||
|
// Updated: 2022-02-27
|
||
|
|
||
|
namespace Index\Serialisation;
|
||
|
|
||
|
use Index\IO\Stream;
|
||
|
|
||
|
/**
|
||
|
* Provides a Base32 serialiser.
|
||
|
*/
|
||
|
class Base32Serialiser extends Serialiser {
|
||
|
private const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
||
|
|
||
|
/**
|
||
|
* Encodes binary data as a Base32 string.
|
||
|
*
|
||
|
* @param mixed $input Input binary data.
|
||
|
* @return string Base32 string representing the binary data.
|
||
|
*/
|
||
|
public function serialise(mixed $input): string {
|
||
|
$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($last, 5, '0', STR_PAD_RIGHT);
|
||
|
|
||
|
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.
|
||
|
*/
|
||
|
public function deserialise(Stream|string $input): mixed {
|
||
|
$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;
|
||
|
}
|
||
|
}
|