-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHexadecimal.php
More file actions
89 lines (69 loc) · 2.41 KB
/
Hexadecimal.php
File metadata and controls
89 lines (69 loc) · 2.41 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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?php
declare(strict_types=1);
namespace TinyBlocks\Encoder\Internal;
final readonly class Hexadecimal
{
private const int DEFAULT_BYTE_COUNT = 0;
private const int HEXADECIMAL_BYTE_LENGTH = 2;
public const string HEXADECIMAL_RADIX = '16';
public const string HEXADECIMAL_ALPHABET = '0123456789abcdef';
private function __construct(
private string $value,
private string $alphabet,
private int $bytes = self::DEFAULT_BYTE_COUNT
) {
}
public static function from(string $value): Hexadecimal
{
return new Hexadecimal(value: $value, alphabet: self::HEXADECIMAL_ALPHABET);
}
public static function fromBinary(string $binary, string $alphabet): Hexadecimal
{
return new Hexadecimal(value: bin2hex($binary), alphabet: $alphabet);
}
public function removeLeadingZeroBytes(): Hexadecimal
{
$bytes = 0;
$newValue = $this->value;
while (str_starts_with($newValue, '00')) {
$bytes++;
$newValue = substr($newValue, self::HEXADECIMAL_BYTE_LENGTH);
}
return new Hexadecimal(value: $newValue, alphabet: $this->alphabet, bytes: $bytes);
}
public function fillWithZeroIfNecessary(): Hexadecimal
{
$newValue = strlen($this->value) % 2 !== 0 ? sprintf('0%s', $this->value) : $this->value;
return new Hexadecimal(value: $newValue, alphabet: $this->alphabet, bytes: $this->bytes);
}
public function getBytes(): int
{
return $this->bytes;
}
public function isEmpty(): bool
{
return empty($this->value);
}
public function toBase(string $base): string
{
$length = strlen($this->value);
$decimalValue = '0';
for ($index = 0; $index < $length; $index++) {
$digit = (string)strpos(self::HEXADECIMAL_ALPHABET, $this->value[$index]);
$decimalValue = bcmul($decimalValue, self::HEXADECIMAL_RADIX);
$decimalValue = bcadd($decimalValue, $digit);
}
$digits = $this->alphabet;
$result = '';
while (bccomp($decimalValue, '0') > 0) {
$remainder = (int)bcmod($decimalValue, $base);
$result = sprintf('%s%s', $digits[$remainder], $result);
$decimalValue = bcdiv($decimalValue, $base);
}
return $result ?: '0';
}
public function toString(): string
{
return $this->value;
}
}