-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBase62.php
More file actions
70 lines (51 loc) · 1.97 KB
/
Base62.php
File metadata and controls
70 lines (51 loc) · 1.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
declare(strict_types=1);
namespace TinyBlocks\Encoder;
use TinyBlocks\Encoder\Internal\Decimal;
use TinyBlocks\Encoder\Internal\Exceptions\InvalidDecoding;
use TinyBlocks\Encoder\Internal\Hexadecimal;
final readonly class Base62 implements Encoder
{
public const int BASE62_RADIX = 62;
private const int BASE62_CHARACTER_LENGTH = 1;
private const string BASE62_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
private function __construct(private string $value)
{
}
public static function from(string $value): Encoder
{
return new Base62(value: $value);
}
public function encode(): string
{
$hexadecimal = Hexadecimal::fromBinary(binary: $this->value, alphabet: self::BASE62_ALPHABET);
$hexadecimal = $hexadecimal->removeLeadingZeroBytes();
$base62 = str_repeat(self::BASE62_ALPHABET[0], $hexadecimal->getBytes());
if ($hexadecimal->isEmpty()) {
return $base62;
}
$base62Value = $hexadecimal->toBase(base: self::BASE62_RADIX);
return sprintf('%s%s', $base62, $base62Value);
}
public function decode(): string
{
if (strlen($this->value) !== strspn($this->value, self::BASE62_ALPHABET)) {
throw new InvalidDecoding(value: $this->value);
}
$bytes = 0;
$value = $this->value;
while (!empty($value) && str_starts_with($value, self::BASE62_ALPHABET[0])) {
$bytes++;
$value = substr($value, self::BASE62_CHARACTER_LENGTH);
}
if (empty($value)) {
return str_repeat("\x00", $bytes);
}
$decimal = Decimal::fromBase62(number: $value, alphabet: self::BASE62_ALPHABET);
$hexadecimal = Hexadecimal::from(value: $decimal->toHexadecimal())
->fillWithZeroIfNecessary()
->toString();
$binary = hex2bin($hexadecimal);
return sprintf('%s%s', str_repeat("\x00", $bytes), $binary);
}
}