From 2132f0f293d856026d7d11bd81b9f4a23a1dc1f6 Mon Sep 17 00:00:00 2001 From: Paragon Initiative Enterprises Date: Mon, 30 Apr 2018 13:57:16 -0400 Subject: [PATCH] Add Base32::encodeUnpadded to v1 branch. --- src/Base32.php | 91 ++++++++++++++++++++++++++++++++------------ tests/Base32Test.php | 10 +++++ 2 files changed, 76 insertions(+), 25 deletions(-) diff --git a/src/Base32.php b/src/Base32.php index 10c59ec..4ede73a 100644 --- a/src/Base32.php +++ b/src/Base32.php @@ -36,22 +36,24 @@ abstract class Base32 implements EncoderInterface * Decode a Base32-encoded string into raw binary * * @param string $src + * @param bool $strictPadding * @return string */ - public static function decode($src) + public static function decode($src, $strictPadding = \false) { - return static::doDecode($src, \false); + return static::doDecode($src, \false, $strictPadding); } /** * Decode an uppercase Base32-encoded string into raw binary * * @param string $src + * @param bool $strictPadding * @return string */ - public static function decodeUpper($src) + public static function decodeUpper($src, $strictPadding = \false) { - return static::doDecode($src, \true); + return static::doDecode($src, \true, $strictPadding); } /** @@ -65,6 +67,18 @@ public static function encode($src) return static::doEncode($src, \false); } + /** + * Encode into Base32 (RFC 4648) + * + * @param string $src + * @return string + * @throws \TypeError + */ + public static function encodeUnpadded($src) + { + return static::doEncode($src, false, false); + } + /** * Encode into uppercase Base32 (RFC 4648) * @@ -76,6 +90,18 @@ public static function encodeUpper($src) return static::doEncode($src, \true); } + /** + * Encode into uppercase Base32 (RFC 4648) + * + * @param string $src + * @return string + * @throws \TypeError + */ + public static function encodeUpperUnpadded($src) + { + return static::doEncode($src, true, false); + } + /** * Uses bitwise operators instead of table-lookups to turn 5-bit integers * into 8-bit integers. @@ -160,9 +186,10 @@ protected static function encode5BitsUpper($src) * * @param string $src * @param bool $upper + * @param bool $strictPadding * @return string */ - protected static function doDecode($src, $upper = \false) + protected static function doDecode($src, $upper = \false, $strictPadding = \true) { // We do this to reduce code duplication: $method = $upper @@ -174,19 +201,24 @@ protected static function doDecode($src, $upper = \false) if ($srcLen === 0) { return ''; } - if (($srcLen & 7) === 0) { - for ($j = 0; $j < 7; ++$j) { - if ($src[$srcLen - 1] === '=') { - $srcLen--; - } else { - break; + if ($strictPadding) { + if (($srcLen & 7) === 0) { + for ($j = 0; $j < 7; ++$j) { + if ($src[$srcLen - 1] === '=') { + $srcLen--; + } else { + break; + } } } - } - if (($srcLen & 7) === 1) { - throw new \RangeException( - 'Incorrect padding' - ); + if (($srcLen & 7) === 1) { + throw new \RangeException( + 'Incorrect padding' + ); + } + } else { + $src = \rtrim($src, '='); + $srcLen = Binary::safeStrlen($src); } $err = 0; @@ -312,9 +344,10 @@ protected static function doDecode($src, $upper = \false) * * @param string $src * @param bool $upper + * @param bool $pad * @return string */ - protected static function doEncode($src, $upper = \false) + protected static function doEncode($src, $upper = \false, $pad = \true) { // We do this to reduce code duplication: $method = $upper @@ -357,8 +390,10 @@ protected static function doEncode($src, $upper = \false) static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . static::$method((($b3 >> 2) ) & 31) . - static::$method((($b3 << 3) ) & 31) . - '='; + static::$method((($b3 << 3) ) & 31); + if ($pad) { + $dest .= '='; + } } elseif ($i + 2 < $srcLen) { $b1 = $chunk[2]; $b2 = $chunk[3]; @@ -367,21 +402,27 @@ protected static function doEncode($src, $upper = \false) static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . - static::$method((($b2 << 1) ) & 31) . - '==='; + static::$method((($b2 << 1) ) & 31); + if ($pad) { + $dest .= '==='; + } } elseif ($i + 1 < $srcLen) { $b1 = $chunk[2]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) ) & 31) . - '===='; + static::$method((($b1 << 4) ) & 31); + if ($pad) { + $dest .= '===='; + } } else { $dest .= static::$method( ($b0 >> 3) & 31) . - static::$method( ($b0 << 2) & 31) . - '======'; + static::$method( ($b0 << 2) & 31); + if ($pad) { + $dest .= '======'; + } } } return $dest; diff --git a/tests/Base32Test.php b/tests/Base32Test.php index 47dac37..12c17e5 100644 --- a/tests/Base32Test.php +++ b/tests/Base32Test.php @@ -21,11 +21,21 @@ public function testRandom() Base32::decode($enc) ); + $this->assertSame( + Base32::encodeUnpadded($random), + \rtrim(Base32::encode($random), '=') + ); + $enc = Base32::encodeUpper($random); $this->assertSame( $random, Base32::decodeUpper($enc) ); + + $this->assertSame( + Base32::encodeUpperUnpadded($random), + \rtrim(Base32::encodeUpper($random), '=') + ); } } }