PHP 8 Compatibility

This commit is contained in:
Frédéric Guillot
2022-02-05 11:49:03 -08:00
committed by GitHub
parent 61e63ef9e0
commit f5bb55bdb8
558 changed files with 6262 additions and 21691 deletions

View File

@@ -3,14 +3,19 @@ base32
Base32 Encoder/Decoder for PHP according to [RFC 4648](https://tools.ietf.org/html/rfc4648).
[![Build Status](https://secure.travis-ci.org/ChristianRiesen/base32.png)](http://travis-ci.org/ChristianRiesen/base32)
[![HHVM Status](http://hhvm.h4cc.de/badge/christian-riesen/base32.png)](http://hhvm.h4cc.de/package/christian-riesen/base32)
![CI](https://github.com/ChristianRiesen/base32/workflows/CI/badge.svg)
[![Latest Stable Version](https://poser.pugx.org/christian-riesen/base32/v/stable.png)](https://packagist.org/packages/christian-riesen/base32) [![Total Downloads](https://poser.pugx.org/christian-riesen/base32/downloads.png)](https://packagist.org/packages/christian-riesen/base32) [![Latest Unstable Version](https://poser.pugx.org/christian-riesen/base32/v/unstable.png)](https://packagist.org/packages/christian-riesen/base32) [![License](https://poser.pugx.org/christian-riesen/base32/license.png)](https://packagist.org/packages/christian-riesen/base32)
Do you like this? Flattr it:
[![Flattr base32](http://api.flattr.com/button/flattr-badge-large.png)](http://flattr.com/thing/720563/ChristianRiesenbase32-on-GitHub)
Installation
-----
Use composer:
```bash
composer require christian-riesen/base32
```
Usage
-----
@@ -23,20 +28,19 @@ use Base32\Base32;
$string = 'fooba';
$encoded = Base32::encode($string);
// $encoded contains now 'MZXW6YTB'
$encoded = Base32::encode($string);
$decoded = Base32::decode($encoded);
// $decoded is again 'fooba'
$decoded = Base32::decode($encoded);
```
You can also use the extended hex alphabet by using the `Base32Hex` class instead.
About
=====
Use
---
Initially created to work with the [one time password project](https://github.com/ChristianRiesen/otp), yet it can stand alone just as well as [Jordi Boggiano](http://seld.be/) kindly pointed out. It's the only Base32 implementation I could make work that passes the test vectors (and contains unit tests).
Initially created to work with the [one time password project](https://github.com/ChristianRiesen/otp), yet it can stand alone just as well as [Jordi Boggiano](http://seld.be/) kindly pointed out. It's the only Base32 implementation that passes the test vectors and contains unit tests as well.
Goal
----
@@ -45,9 +49,9 @@ Have a RFC compliant Base32 encoder and decoder. The implementation could be imp
Requirements
------------
PHP 5.3 to 5.6 or 7.0+
Works on PHP 7.2 and later, including PHP 8.0.
If you want to run the tests, PHPUnit 5.0+ or up is required. Tests require PHP 5.6 or 7.0+.
Tests run on PHPUnit 9.5, with PHP 7.3 and later. For PHP 7.2, tests use an older PHPUnit version.
Author
------

View File

@@ -1,146 +1,168 @@
<?php
declare(strict_types=1);
namespace Base32;
/**
* Base32 encoder and decoder
*
* Last update: 2012-06-20
* Base32 encoder and decoder.
*
* RFC 4648 compliant
* @link http://www.ietf.org/rfc/rfc4648.txt
*
* @see http://www.ietf.org/rfc/rfc4648.txt
* Some groundwork based on this class
* https://github.com/NTICompass/PHP-Base32
*
* @author Christian Riesen <chris.riesen@gmail.com>
* @link http://christianriesen.com
* @author Christian Riesen <chris.riesen@gmail.com>
* @author Sam Williams <sam@badcow.co>
*
* @see http://christianriesen.com
*
* @license MIT License see LICENSE file
*/
class Base32
{
/**
* Alphabet for encoding and decoding base32
* Alphabet for encoding and decoding base32.
*
* @var array
* @var string
*/
private static $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=';
protected const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=';
protected const BASE32HEX_PATTERN = '/[^A-Z2-7]/';
/**
* Creates an array from a binary string into a given chunk size
*
* @param string $binaryString String to chunk
* @param integer $bits Number of bits per chunk
* @return array
* Maps the Base32 character to its corresponding bit value.
*/
private static function chunk($binaryString, $bits)
{
$binaryString = chunk_split($binaryString, $bits, ' ');
if (substr($binaryString, (strlen($binaryString)) - 1) == ' ') {
$binaryString = substr($binaryString, 0, strlen($binaryString)-1);
}
return explode(' ', $binaryString);
}
protected const MAPPING = [
'=' => 0b00000,
'A' => 0b00000,
'B' => 0b00001,
'C' => 0b00010,
'D' => 0b00011,
'E' => 0b00100,
'F' => 0b00101,
'G' => 0b00110,
'H' => 0b00111,
'I' => 0b01000,
'J' => 0b01001,
'K' => 0b01010,
'L' => 0b01011,
'M' => 0b01100,
'N' => 0b01101,
'O' => 0b01110,
'P' => 0b01111,
'Q' => 0b10000,
'R' => 0b10001,
'S' => 0b10010,
'T' => 0b10011,
'U' => 0b10100,
'V' => 0b10101,
'W' => 0b10110,
'X' => 0b10111,
'Y' => 0b11000,
'Z' => 0b11001,
'2' => 0b11010,
'3' => 0b11011,
'4' => 0b11100,
'5' => 0b11101,
'6' => 0b11110,
'7' => 0b11111,
];
/**
* Encodes into base32
* Encodes into base32.
*
* @param string $string Clear text string
*
* @return string Base32 encoded string
*/
public static function encode($string)
public static function encode(string $string): string
{
if (strlen($string) == 0) {
// Gives an empty string
// Empty string results in empty string
if ('' === $string) {
return '';
}
// Convert string to binary
$binaryString = '';
$encoded = '';
foreach (str_split($string) as $s) {
// Return each character as an 8-bit binary string
$binaryString .= sprintf('%08b', ord($s));
}
//Set the initial values
$n = $bitLen = $val = 0;
$len = \strlen($string);
// Break into 5-bit chunks, then break that into an array
$binaryArray = self::chunk($binaryString, 5);
//Pad the end of the string - this ensures that there are enough zeros
$string .= \str_repeat(\chr(0), 4);
// Pad array to be divisible by 8
while (count($binaryArray) % 8 !== 0) {
$binaryArray[] = null;
}
//Explode string into integers
$chars = (array) \unpack('C*', $string, 0);
$base32String = '';
// Encode in base32
foreach ($binaryArray as $bin) {
$char = 32;
if (!is_null($bin)) {
// Pad the binary strings
$bin = str_pad($bin, 5, 0, STR_PAD_RIGHT);
$char = bindec($bin);
while ($n < $len || 0 !== $bitLen) {
//If the bit length has fallen below 5, shift left 8 and add the next character.
if ($bitLen < 5) {
$val = $val << 8;
$bitLen += 8;
$n++;
$val += $chars[$n];
}
// Base32 character
$base32String .= self::$alphabet[$char];
$shift = $bitLen - 5;
$encoded .= ($n - (int)($bitLen > 8) > $len && 0 == $val) ? '=' : static::ALPHABET[$val >> $shift];
$val = $val & ((1 << $shift) - 1);
$bitLen -= 5;
}
return $base32String;
return $encoded;
}
/**
* Decodes base32
* Decodes base32.
*
* @param string $base32String Base32 encoded string
*
* @return string Clear text string
*/
public static function decode($base32String)
public static function decode(string $base32String): string
{
// Only work in upper cases
$base32String = strtoupper($base32String);
$base32String = \strtoupper($base32String);
// Remove anything that is not base32 alphabet
$pattern = '/[^A-Z2-7]/';
$base32String = \preg_replace(static::BASE32HEX_PATTERN, '', $base32String);
$base32String = preg_replace($pattern, '', $base32String);
if (strlen($base32String) == 0) {
// Gives an empty string
// Empty string results in empty string
if ('' === $base32String || null === $base32String) {
return '';
}
$base32Array = str_split($base32String);
$decoded = '';
$string = '';
//Set the initial values
$len = \strlen($base32String);
$n = 0;
$bitLen = 5;
$val = static::MAPPING[$base32String[0]];
foreach ($base32Array as $str) {
$char = strpos(self::$alphabet, $str);
while ($n < $len) {
//If the bit length has fallen below 8, shift left 5 and add the next pentet.
if ($bitLen < 8) {
$val = $val << 5;
$bitLen += 5;
$n++;
$pentet = $base32String[$n] ?? '=';
// Ignore the padding character
if ($char !== 32) {
$string .= sprintf('%05b', $char);
//If the new pentet is padding, make this the last iteration.
if ('=' === $pentet) {
$n = $len;
}
$val += static::MAPPING[$pentet];
continue;
}
$shift = $bitLen - 8;
$decoded .= \chr($val >> $shift);
$val = $val & ((1 << $shift) - 1);
$bitLen -= 8;
}
while (strlen($string) %8 !== 0) {
$string = substr($string, 0, strlen($string)-1);
}
$binaryArray = self::chunk($string, 8);
$realString = '';
foreach ($binaryArray as $bin) {
// Pad each value to 8 bits
$bin = str_pad($bin, 8, 0, STR_PAD_RIGHT);
// Convert binary strings to ASCII
$realString .= chr(bindec($bin));
}
return $realString;
return $decoded;
}
}

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace Base32;
/**
* Base32Hex encoder and decoder.
*
* RFC 4648 compliant
* @see http://www.ietf.org/rfc/rfc4648.txt
*
* @author Sam Williams <sam@badcow.co>
*
* @see http://christianriesen.com
*
* @license MIT License see LICENSE file
*/
class Base32Hex extends Base32
{
/**
* Alphabet for encoding and decoding base32 extended hex.
*
* @var string
*/
protected const ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUV=';
protected const BASE32HEX_PATTERN = '/[^0-9A-V]/';
/**
* Maps the Base32 character to its corresponding bit value.
*/
protected const MAPPING = [
'=' => 0b00000,
'0' => 0b00000,
'1' => 0b00001,
'2' => 0b00010,
'3' => 0b00011,
'4' => 0b00100,
'5' => 0b00101,
'6' => 0b00110,
'7' => 0b00111,
'8' => 0b01000,
'9' => 0b01001,
'A' => 0b01010,
'B' => 0b01011,
'C' => 0b01100,
'D' => 0b01101,
'E' => 0b01110,
'F' => 0b01111,
'G' => 0b10000,
'H' => 0b10001,
'I' => 0b10010,
'J' => 0b10011,
'K' => 0b10100,
'L' => 0b10101,
'M' => 0b10110,
'N' => 0b10111,
'O' => 0b11000,
'P' => 0b11001,
'Q' => 0b11010,
'R' => 0b11011,
'S' => 0b11100,
'T' => 0b11101,
'U' => 0b11110,
'V' => 0b11111,
];
}