Skip to content

Commit

Permalink
Improve base32 package implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Mar 22, 2024
1 parent 4ab2451 commit 5c0bde3
Showing 1 changed file with 21 additions and 19 deletions.
40 changes: 21 additions & 19 deletions src/Base32/Base32.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ final class Base32
private function __construct(string $alphabet, string $padding)
{
$normalizeAlphabet = strtoupper($alphabet);

[$this->alphabet, $this->padding] = match (true) {
1 !== strlen($padding) => throw new ValueError('The padding character must a single character.'),
"\r" === $padding => throw new ValueError('The padding character can not be the carriage return character.'),
Expand All @@ -31,7 +30,7 @@ private function __construct(string $alphabet, string $padding)
str_contains($alphabet, "\r") => throw new ValueError('The alphabet can not contain the carriage return character.'),
str_contains($alphabet, "\n") => throw new ValueError('The alphabet can not contain the newline escape sequence.'),
str_contains($normalizeAlphabet, strtoupper($padding)) => throw new ValueError('The alphabet can not contain the padding character.'),
self::ALPHABET_SIZE !== count(array_unique(str_split($normalizeAlphabet))) => throw new ValueError('The alphabet must contain unique characters.'),
self::ALPHABET_SIZE !== strlen(count_chars($normalizeAlphabet, 3)) => throw new ValueError('The alphabet must contain unique characters.'), /* @phpstan-ignore-line */
default => [$alphabet, $padding],
};
}
Expand All @@ -52,10 +51,12 @@ public function decode(string $encoded, bool $strict = false): string
}

$alphabet = $this->alphabet;
$padding = $this->padding;
$encoded = str_replace(["\r", "\n"], [''], $encoded);
if (!$strict) {
$alphabet = strtoupper($alphabet);
$encoded = str_replace(strtoupper($this->padding), $this->padding, strtoupper($encoded));
$padding = strtoupper($padding);
$encoded = str_replace($padding, $this->padding, strtoupper($encoded));
}

$remainder = strlen($encoded) % 8;
Expand All @@ -64,10 +65,23 @@ public function decode(string $encoded, bool $strict = false): string
throw new RuntimeException('The encoded data length is invalid.');
}

$encoded .= str_repeat($this->padding, $remainder);
$encoded .= str_repeat($padding, $remainder);
}

$inside = rtrim($encoded, $padding);
$end = substr($encoded, strlen($inside));
if ($strict && !in_array(strlen($end), [3, 4, 6, 0], true)) {
throw new RuntimeException('The encoded data contains an invalid padding character length.');
}

if (str_contains($inside, $padding)) {
if ($strict) {
throw new RuntimeException('The encoded data contains the padding character.');
}
$encoded = str_replace($padding, '', $inside).$end;
}

$characters = $alphabet.$this->padding;
$characters = $alphabet.$padding;
if (strspn($encoded, $characters) !== strlen($encoded)) {
if ($strict) {
throw new RuntimeException('The encoded data contains characters unknown to the alphabet.');
Expand All @@ -78,18 +92,6 @@ public function decode(string $encoded, bool $strict = false): string
}
}

$inside = rtrim($encoded, $this->padding);
if (str_contains($inside, $this->padding)) {
if ($strict) {
throw new RuntimeException('The encoded data contains the padding character.');
}
$encoded = str_replace($this->padding, '', $inside).substr($encoded, strlen($inside));
}

if ($strict && 1 !== preg_match('/^[^'.$this->padding.']+(('.$this->padding.'){3,4}|('.$this->padding.'){6}|'.$this->padding.')?$/', $encoded)) {
throw new RuntimeException('The encoded data contains the padding character.');
}

$decoded = '';
$offset = 0;
$bitLen = 5;
Expand All @@ -101,8 +103,8 @@ public function decode(string $encoded, bool $strict = false): string
if ($bitLen < 8) {
$bitLen += 5;
$offset++;
$pentet = $encoded[$offset] ?? $this->padding;
if ($this->padding === $pentet) {
$pentet = $encoded[$offset] ?? $padding;
if ($padding === $pentet) {
$offset = $length;
}
$val = ($val << 5) + $chars[$pentet];
Expand Down

0 comments on commit 5c0bde3

Please sign in to comment.