-
-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Encoding\Base64; | ||
|
||
use Psl\Encoding\Exception; | ||
|
||
use function base64_decode; | ||
use function preg_match; | ||
use Psl\Str; | ||
|
||
/** | ||
* Decode a base64-encoded string into raw binary. | ||
* | ||
* Base64 character set: | ||
* [A-Z] [a-z] [0-9] + / | ||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f | ||
* | ||
* @psalm-pure | ||
* | ||
* @throws Exception\RangeException If the encoded string contains characters outside | ||
* the base64 characters range. | ||
*/ | ||
function decode(string $base64): string | ||
{ | ||
if (!preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $base64)) { | ||
throw new Exception\RangeException( | ||
'The given base64 string contains characters outside the base64 range.' | ||
); | ||
} | ||
|
||
$remainder = Str\length($base64) % 4; | ||
if (0 !== $remainder) { | ||
throw new Exception\IncorrectPaddingException( | ||
'The given base64 string has incorrect padding.' | ||
); | ||
} | ||
|
||
/** @var string|false $result */ | ||
$result = base64_decode($base64, true); | ||
if (false === $result) { | ||
throw new Exception\IncorrectPaddingException( | ||
'The given base64 string has incorrect padding.' | ||
); | ||
} | ||
|
||
return $result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Encoding\Base64; | ||
|
||
use function base64_encode; | ||
|
||
/** | ||
* Convert a binary string into a base64-encoded string. | ||
* | ||
* Base64 character set: | ||
* [A-Z] [a-z] [0-9] + / | ||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f | ||
* | ||
* @psalm-pure | ||
*/ | ||
function encode(string $binary): string | ||
{ | ||
return base64_encode($binary); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Encoding\Exception; | ||
|
||
use Psl\Exception; | ||
|
||
interface ExceptionInterface extends Exception\ExceptionInterface | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Encoding\Exception; | ||
|
||
use Psl\Exception; | ||
|
||
final class IncorrectPaddingException extends Exception\InvalidArgumentException implements ExceptionInterface | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Encoding\Exception; | ||
|
||
final class RangeException extends \RangeException implements ExceptionInterface | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Encoding\Hex; | ||
|
||
use Psl\Encoding\Exception; | ||
use Psl\Str; | ||
|
||
/** | ||
* Convert a hexadecimal string into a binary string. | ||
* | ||
* Hex ( Base16 ) character set: | ||
* [0-9] [a-f] [A-F] | ||
* 0x30-0x39, 0x61-0x66, 0x41-0x46 | ||
* | ||
* @psalm-pure | ||
* | ||
* @throws Exception\RangeException If the hexadecimal string contains characters outside the base16 range, | ||
* or an odd number of characters. | ||
*/ | ||
function decode(string $hexadecimal): string | ||
{ | ||
if (!ctype_xdigit($hexadecimal)) { | ||
throw new Exception\RangeException( | ||
'The given hexadecimal string contains characters outside the base16 range.' | ||
); | ||
} | ||
|
||
/** @psalm-suppress MissingThrowsDocblock */ | ||
$hex_len = Str\length($hexadecimal, '8bit'); | ||
if (($hex_len & 1) !== 0) { | ||
throw new Exception\RangeException( | ||
'Expected an even number of hexadecimal characters.', | ||
); | ||
} | ||
|
||
return hex2bin($hexadecimal); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Encoding\Hex; | ||
|
||
/** | ||
* Convert a binary string into a hexadecimal string. | ||
* | ||
* Hex ( Base16 ) character set: | ||
* [0-9] [a-f] | ||
* 0x30-0x39, 0x61-0x66 | ||
* | ||
* @psalm-pure | ||
*/ | ||
function encode(string $binary): string | ||
{ | ||
return bin2hex($binary); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Tests\Encoding; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Psl\Encoding\Base64; | ||
use Psl\Encoding\Exception; | ||
use Psl\SecureRandom; | ||
|
||
final class Base64Test extends TestCase | ||
{ | ||
/** | ||
* @dataProvider provideRandomBytes | ||
*/ | ||
public function testEncodeAndDecode(string $random): void | ||
{ | ||
$encoded = Base64\encode($random); | ||
static::assertSame($random, Base64\decode($encoded)); | ||
} | ||
|
||
public function testDecodeThrowsForCharactersOutsideTheBase64Range(): void | ||
{ | ||
$this->expectException(Exception\RangeException::class); | ||
|
||
Base64\decode('@~=='); | ||
} | ||
|
||
public function provideRandomBytes(): iterable | ||
{ | ||
for ($i = 1; $i < 128; ++$i) { | ||
yield [SecureRandom\bytes($i)]; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Psl\Tests\Encoding; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Psl\Encoding\Exception; | ||
use Psl\Encoding\Hex; | ||
use Psl\SecureRandom; | ||
|
||
use function bin2hex; | ||
|
||
final class HexTest extends TestCase | ||
{ | ||
/** | ||
* @dataProvider provideRandomBytes | ||
*/ | ||
public function testRandom(string $random): void | ||
{ | ||
$enc = Hex\encode($random); | ||
static::assertSame($random, Hex\decode($enc)); | ||
static::assertSame(bin2hex($random), $enc); | ||
$enc = Hex\encode($random); | ||
static::assertSame($random, Hex\decode($enc)); | ||
} | ||
|
||
public function testDecodeThrowsForCharactersOutsideTheHexRange(): void | ||
{ | ||
$this->expectException(Exception\RangeException::class); | ||
|
||
Hex\decode('gf'); | ||
} | ||
|
||
public function testDecodeThrowsForAnOddNumberOfCharacters(): void | ||
{ | ||
$this->expectException(Exception\RangeException::class); | ||
|
||
Hex\decode('f'); | ||
} | ||
|
||
public function provideRandomBytes(): iterable | ||
{ | ||
for ($i = 1; $i < 128; ++$i) { | ||
yield [SecureRandom\bytes($i)]; | ||
} | ||
} | ||
} |