mirror of
https://github.com/PrivateBin/PrivateBin.git
synced 2026-03-05 13:30:32 -05:00
update ip-lib library from 1.20.0 to 1.21.0
This commit is contained in:
1
vendor/composer/autoload_classmap.php
vendored
1
vendor/composer/autoload_classmap.php
vendored
@@ -22,6 +22,7 @@ return array(
|
||||
'IPLib\\Range\\Subnet' => $vendorDir . '/mlocati/ip-lib/src/Range/Subnet.php',
|
||||
'IPLib\\Range\\Type' => $vendorDir . '/mlocati/ip-lib/src/Range/Type.php',
|
||||
'IPLib\\Service\\BinaryMath' => $vendorDir . '/mlocati/ip-lib/src/Service/BinaryMath.php',
|
||||
'IPLib\\Service\\NumberInChunks' => $vendorDir . '/mlocati/ip-lib/src/Service/NumberInChunks.php',
|
||||
'IPLib\\Service\\RangesFromBoundaryCalculator' => $vendorDir . '/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php',
|
||||
'IPLib\\Service\\UnsignedIntegerMath' => $vendorDir . '/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php',
|
||||
'Identicon\\Generator\\BaseGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/BaseGenerator.php',
|
||||
|
||||
1
vendor/composer/autoload_static.php
vendored
1
vendor/composer/autoload_static.php
vendored
@@ -70,6 +70,7 @@ class ComposerStaticInitDontChange
|
||||
'IPLib\\Range\\Subnet' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Subnet.php',
|
||||
'IPLib\\Range\\Type' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Type.php',
|
||||
'IPLib\\Service\\BinaryMath' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/BinaryMath.php',
|
||||
'IPLib\\Service\\NumberInChunks' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/NumberInChunks.php',
|
||||
'IPLib\\Service\\RangesFromBoundaryCalculator' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php',
|
||||
'IPLib\\Service\\UnsignedIntegerMath' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php',
|
||||
'Identicon\\Generator\\BaseGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/BaseGenerator.php',
|
||||
|
||||
10
vendor/composer/installed.php
vendored
10
vendor/composer/installed.php
vendored
@@ -3,7 +3,7 @@
|
||||
'name' => 'privatebin/privatebin',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '3ba29ea29e04d8a16d64e0f49994ba416c1b008f',
|
||||
'reference' => '06496a1b0e975b79c5a7abc0bd54b492ca264640',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -20,9 +20,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'mlocati/ip-lib' => array(
|
||||
'pretty_version' => '1.20.0',
|
||||
'version' => '1.20.0.0',
|
||||
'reference' => 'fd45fc3bf08ed6c7e665e2e70562082ac954afd4',
|
||||
'pretty_version' => '1.21.0',
|
||||
'version' => '1.21.0.0',
|
||||
'reference' => 'b5d38cdcbfc1516604d821a1f3f4a1638f327267',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../mlocati/ip-lib',
|
||||
'aliases' => array(),
|
||||
@@ -31,7 +31,7 @@
|
||||
'privatebin/privatebin' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '3ba29ea29e04d8a16d64e0f49994ba416c1b008f',
|
||||
'reference' => '06496a1b0e975b79c5a7abc0bd54b492ca264640',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
@@ -110,11 +110,12 @@ interface AddressInterface
|
||||
/**
|
||||
* Get the address at a certain distance from this address.
|
||||
*
|
||||
* @param int $n the distance of the address (can be negative)
|
||||
* @param int|numeric-string $n the distance of the address (can be negative)
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null return NULL if $n is not an integer or if the final address would be invalid
|
||||
* @return \IPLib\Address\AddressInterface|null return NULL if $n is not an integer or NULL if $n is neither an integer nor a string containing a valid integer, or if the final address would be invalid
|
||||
*
|
||||
* @since 1.15.0
|
||||
* @since 1.21.0 $n can also be a numeric string
|
||||
*
|
||||
* @example passing 1 to the address 127.0.0.1 will result in 127.0.0.2
|
||||
* @example passing -1 to the address 127.0.0.1 will result in 127.0.0.0
|
||||
|
||||
36
vendor/mlocati/ip-lib/src/Address/IPv4.php
vendored
36
vendor/mlocati/ip-lib/src/Address/IPv4.php
vendored
@@ -6,6 +6,8 @@ use IPLib\ParseStringFlag;
|
||||
use IPLib\Range\RangeInterface;
|
||||
use IPLib\Range\Subnet;
|
||||
use IPLib\Range\Type as RangeType;
|
||||
use IPLib\Service\BinaryMath;
|
||||
use IPLib\Service\NumberInChunks;
|
||||
|
||||
/**
|
||||
* An IPv4 address.
|
||||
@@ -456,28 +458,24 @@ class IPv4 implements AddressInterface
|
||||
*/
|
||||
public function getAddressAtOffset($n)
|
||||
{
|
||||
if (!is_int($n)) {
|
||||
if (is_int($n)) {
|
||||
$thatChunks = NumberInChunks::fromInteger($n, NumberInChunks::CHUNKSIZE_BYTES);
|
||||
} elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') {
|
||||
$thatChunks = NumberInChunks::fromNumericString($s, NumberInChunks::CHUNKSIZE_BYTES);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
$myBytes = $this->getBytes();
|
||||
while (isset($myBytes[1]) && $myBytes[0] === 0) {
|
||||
array_shift($myBytes);
|
||||
}
|
||||
$myChunks = new NumberInChunks(false, $myBytes, NumberInChunks::CHUNKSIZE_BYTES);
|
||||
$result = $myChunks->add($thatChunks);
|
||||
if ($result->negative || count($result->chunks) > 4) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$boundary = 256;
|
||||
$mod = $n;
|
||||
$bytes = $this->getBytes();
|
||||
for ($i = count($bytes) - 1; $i >= 0; $i--) {
|
||||
$tmp = ($bytes[$i] + $mod) % $boundary;
|
||||
$mod = (int) floor(($bytes[$i] + $mod) / $boundary);
|
||||
if ($tmp < 0) {
|
||||
$tmp += $boundary;
|
||||
}
|
||||
|
||||
$bytes[$i] = $tmp;
|
||||
}
|
||||
|
||||
if ($mod !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return static::fromBytes($bytes);
|
||||
return static::fromBytes(array_pad($result->chunks, -4, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
38
vendor/mlocati/ip-lib/src/Address/IPv6.php
vendored
38
vendor/mlocati/ip-lib/src/Address/IPv6.php
vendored
@@ -6,6 +6,8 @@ use IPLib\ParseStringFlag;
|
||||
use IPLib\Range\RangeInterface;
|
||||
use IPLib\Range\Subnet;
|
||||
use IPLib\Range\Type as RangeType;
|
||||
use IPLib\Service\BinaryMath;
|
||||
use IPLib\Service\NumberInChunks;
|
||||
|
||||
/**
|
||||
* An IPv6 address.
|
||||
@@ -549,28 +551,24 @@ class IPv6 implements AddressInterface
|
||||
*/
|
||||
public function getAddressAtOffset($n)
|
||||
{
|
||||
if (!is_int($n)) {
|
||||
if (is_int($n)) {
|
||||
$thatChunks = NumberInChunks::fromInteger($n, NumberInChunks::CHUNKSIZE_WORDS);
|
||||
} elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') {
|
||||
$thatChunks = NumberInChunks::fromNumericString($s, NumberInChunks::CHUNKSIZE_WORDS);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
$myWords = $this->getWords();
|
||||
while (isset($myWords[1]) && $myWords[0] === 0) {
|
||||
array_shift($myWords);
|
||||
}
|
||||
$myChunks = new NumberInChunks(false, $myWords, NumberInChunks::CHUNKSIZE_WORDS);
|
||||
$result = $myChunks->add($thatChunks);
|
||||
if ($result->negative || count($result->chunks) > 8) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$boundary = 0x10000;
|
||||
$mod = $n;
|
||||
$words = $this->getWords();
|
||||
for ($i = count($words) - 1; $i >= 0; $i--) {
|
||||
$tmp = ($words[$i] + $mod) % $boundary;
|
||||
$mod = (int) floor(($words[$i] + $mod) / $boundary);
|
||||
if ($tmp < 0) {
|
||||
$tmp += $boundary;
|
||||
}
|
||||
|
||||
$words[$i] = $tmp;
|
||||
}
|
||||
|
||||
if ($mod !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return static::fromWords($words);
|
||||
return static::fromWords(array_pad($result->chunks, -8, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -645,7 +643,7 @@ class IPv6 implements AddressInterface
|
||||
}
|
||||
$myWords = $this->getWords();
|
||||
$otherWords = $other->getWords();
|
||||
$sum = array_fill(0, 7, 0);
|
||||
$sum = array_fill(0, 8, 0);
|
||||
$carry = 0;
|
||||
for ($index = 7; $index >= 0; $index--) {
|
||||
$word = $myWords[$index] + $otherWords[$index] + $carry;
|
||||
|
||||
@@ -7,6 +7,7 @@ use IPLib\Address\IPv4;
|
||||
use IPLib\Address\IPv6;
|
||||
use IPLib\Address\Type as AddressType;
|
||||
use IPLib\Factory;
|
||||
use IPLib\Service\BinaryMath;
|
||||
use OutOfBoundsException;
|
||||
|
||||
/**
|
||||
@@ -59,17 +60,26 @@ abstract class AbstractRange implements RangeInterface
|
||||
*/
|
||||
public function getAddressAtOffset($n)
|
||||
{
|
||||
if (!is_int($n)) {
|
||||
if (is_int($n)) {
|
||||
$positive = $n >= 0;
|
||||
if ($positive === false) {
|
||||
$nPlus1 = $n + 1;
|
||||
}
|
||||
} elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') {
|
||||
$n = $s;
|
||||
$positive = $n[0] !== '-';
|
||||
if ($positive === false) {
|
||||
$nPlus1 = BinaryMath::getInstance()->add1ToIntegerString($n);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$address = null;
|
||||
if ($n >= 0) {
|
||||
if ($positive) {
|
||||
$start = Factory::parseAddressString($this->getComparableStartString());
|
||||
$address = $start->getAddressAtOffset($n);
|
||||
} else {
|
||||
$end = Factory::parseAddressString($this->getComparableEndString());
|
||||
$address = $end->getAddressAtOffset($n + 1);
|
||||
$address = $end->getAddressAtOffset($nPlus1);
|
||||
}
|
||||
|
||||
if ($address === null) {
|
||||
|
||||
17
vendor/mlocati/ip-lib/src/Range/Pattern.php
vendored
17
vendor/mlocati/ip-lib/src/Range/Pattern.php
vendored
@@ -7,6 +7,7 @@ use IPLib\Address\IPv4;
|
||||
use IPLib\Address\IPv6;
|
||||
use IPLib\Address\Type as AddressType;
|
||||
use IPLib\ParseStringFlag;
|
||||
use IPLib\Service\BinaryMath;
|
||||
|
||||
/**
|
||||
* Represents an address range in pattern format (only ending asterisks are supported).
|
||||
@@ -304,7 +305,21 @@ class Pattern extends AbstractRange
|
||||
$maxPrefix = $fromAddress::getNumberOfBits();
|
||||
$prefix = $this->getNetworkPrefix();
|
||||
|
||||
return pow(2, ($maxPrefix - $prefix));
|
||||
return pow(2, $maxPrefix - $prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::getExactSize()
|
||||
*/
|
||||
public function getExactSize()
|
||||
{
|
||||
$fromAddress = $this->fromAddress;
|
||||
$maxPrefix = $fromAddress::getNumberOfBits();
|
||||
$prefix = $this->getNetworkPrefix();
|
||||
|
||||
return BinaryMath::getInstance()->pow2string($maxPrefix - $prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,11 +46,12 @@ interface RangeInterface
|
||||
/**
|
||||
* Get the address at a certain offset of this range.
|
||||
*
|
||||
* @param int $n the offset of the address (support negative offset)
|
||||
* @param int|numeric-string $n the offset of the address (support negative offset)
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null return NULL if $n is not an integer or if the offset out of range
|
||||
* @return \IPLib\Address\AddressInterface|null return NULL if $n is neither an integer nor a string containing a valid integer, or if the offset out of range
|
||||
*
|
||||
* @since 1.15.0
|
||||
* @since 1.21.0 $n can also be a numeric string
|
||||
*
|
||||
* @example passing 256 to the range 127.0.0.0/16 will result in 127.0.1.0
|
||||
* @example passing -1 to the range 127.0.1.0/16 will result in 127.0.255.255
|
||||
@@ -150,14 +151,23 @@ interface RangeInterface
|
||||
public function getReverseDNSLookupName();
|
||||
|
||||
/**
|
||||
* Get the count of addresses this IP range contains.
|
||||
* Get the count of addresses contained in this IP range (possibly approximated).
|
||||
*
|
||||
* @return int|float Return float as for huge IPv6 networks, int is not enough
|
||||
* @return int|float If the number of addresses exceeds PHP_INT_MAX a float containing an approximation will be returned
|
||||
*
|
||||
* @since 1.16.0
|
||||
*/
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Get the exact count of addresses contained in this IP range.
|
||||
*
|
||||
* @return int|numeric-string If the number of addresses exceeds PHP_INT_MAX a string containing the exact number of addresses will be returned
|
||||
*
|
||||
* @since 1.21.0
|
||||
*/
|
||||
public function getExactSize();
|
||||
|
||||
/**
|
||||
* Get the "network prefix", that is how many bits of the address are dedicated to the network portion.
|
||||
*
|
||||
|
||||
10
vendor/mlocati/ip-lib/src/Range/Single.php
vendored
10
vendor/mlocati/ip-lib/src/Range/Single.php
vendored
@@ -237,6 +237,16 @@ class Single extends AbstractRange
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::getExactSize()
|
||||
*/
|
||||
public function getExactSize()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
|
||||
17
vendor/mlocati/ip-lib/src/Range/Subnet.php
vendored
17
vendor/mlocati/ip-lib/src/Range/Subnet.php
vendored
@@ -7,6 +7,7 @@ use IPLib\Address\IPv4;
|
||||
use IPLib\Address\Type as AddressType;
|
||||
use IPLib\Factory;
|
||||
use IPLib\ParseStringFlag;
|
||||
use IPLib\Service\BinaryMath;
|
||||
|
||||
/**
|
||||
* Represents an address range in subnet format (eg CIDR).
|
||||
@@ -348,6 +349,20 @@ class Subnet extends AbstractRange
|
||||
$maxPrefix = $fromAddress::getNumberOfBits();
|
||||
$prefix = $this->getNetworkPrefix();
|
||||
|
||||
return pow(2, ($maxPrefix - $prefix));
|
||||
return pow(2, $maxPrefix - $prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::getExactSize()
|
||||
*/
|
||||
public function getExactSize()
|
||||
{
|
||||
$fromAddress = $this->fromAddress;
|
||||
$maxPrefix = $fromAddress::getNumberOfBits();
|
||||
$prefix = $this->getNetworkPrefix();
|
||||
|
||||
return BinaryMath::getInstance()->pow2string($maxPrefix - $prefix);
|
||||
}
|
||||
}
|
||||
|
||||
22
vendor/mlocati/ip-lib/src/Range/Type.php
vendored
22
vendor/mlocati/ip-lib/src/Range/Type.php
vendored
@@ -120,29 +120,29 @@ class Type
|
||||
case static::T_UNSPECIFIED:
|
||||
return 'Unspecified/unknown address';
|
||||
case static::T_RESERVED:
|
||||
return 'Reserved/internal use only';
|
||||
return 'Reserved/internal use only';
|
||||
case static::T_THISNETWORK:
|
||||
return 'Refer to source hosts on "this" network';
|
||||
return 'Refer to source hosts on "this" network';
|
||||
case static::T_LOOPBACK:
|
||||
return 'Internet host loopback address';
|
||||
return 'Internet host loopback address';
|
||||
case static::T_ANYCASTRELAY:
|
||||
return 'Relay anycast address';
|
||||
return 'Relay anycast address';
|
||||
case static::T_LIMITEDBROADCAST:
|
||||
return '"Limited broadcast" destination address';
|
||||
return '"Limited broadcast" destination address';
|
||||
case static::T_MULTICAST:
|
||||
return 'Multicast address assignments - Indentify a group of interfaces';
|
||||
return 'Multicast address assignments - Indentify a group of interfaces';
|
||||
case static::T_LINKLOCAL:
|
||||
return '"Link local" address, allocated for communication between hosts on a single link';
|
||||
return '"Link local" address, allocated for communication between hosts on a single link';
|
||||
case static::T_LINKLOCAL_UNICAST:
|
||||
return 'Link local unicast / Linked-scoped unicast';
|
||||
case static::T_DISCARDONLY:
|
||||
return 'Discard only';
|
||||
return 'Discard only';
|
||||
case static::T_DISCARD:
|
||||
return 'Discard';
|
||||
return 'Discard';
|
||||
case static::T_PRIVATENETWORK:
|
||||
return 'For use in private networks';
|
||||
return 'For use in private networks';
|
||||
case static::T_PUBLIC:
|
||||
return 'Public address';
|
||||
return 'Public address';
|
||||
case static::T_CGNAT:
|
||||
return 'Carrier-grade NAT';
|
||||
default:
|
||||
|
||||
112
vendor/mlocati/ip-lib/src/Service/BinaryMath.php
vendored
112
vendor/mlocati/ip-lib/src/Service/BinaryMath.php
vendored
@@ -9,6 +9,20 @@ namespace IPLib\Service;
|
||||
*/
|
||||
class BinaryMath
|
||||
{
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* @return \IPLib\Service\BinaryMath
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim the leading zeroes from a non-negative integer represented in binary form.
|
||||
*
|
||||
@@ -97,6 +111,104 @@ class BinaryMath
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute 2 raised to the given exponent.
|
||||
*
|
||||
* If the result fits into a native PHP integer, an int is returned.
|
||||
* If the result exceeds PHP_INT_MAX, a string containing the exact decimal representation is returned.
|
||||
*
|
||||
* @param int $exponent The non-negative exponent
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public function pow2string($exponent)
|
||||
{
|
||||
if ($exponent < PHP_INT_SIZE * 8 - 1) {
|
||||
return 1 << $exponent;
|
||||
}
|
||||
$digits = array(1);
|
||||
for ($i = 0; $i < $exponent; $i++) {
|
||||
$carry = 0;
|
||||
foreach ($digits as $index => $digit) {
|
||||
$product = $digit * 2 + $carry;
|
||||
$digits[$index] = $product % 10;
|
||||
$carry = (int) ($product / 10);
|
||||
}
|
||||
if ($carry !== 0) {
|
||||
$digits[] = $carry;
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', array_reverse($digits));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param numeric-string|mixed $value
|
||||
*
|
||||
* @return string empty string if $value is not a valid numeric string
|
||||
*/
|
||||
public function normalizeIntegerString($value)
|
||||
{
|
||||
if (!is_string($value) || $value === '') {
|
||||
return '';
|
||||
}
|
||||
$sign = $value[0];
|
||||
if ($sign === '-' || $sign === '+') {
|
||||
$value = substr($value, 1);
|
||||
}
|
||||
$matches = null;
|
||||
if (!preg_match('/^0*([0-9]+)$/', $value, $matches)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return ($sign === '-' && $matches[1] !== '0' ? $sign : '') . $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param numeric-string $value a string that has been normalized with normalizeIntegerString()
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function add1ToIntegerString($value)
|
||||
{
|
||||
if ($value[0] === '-') {
|
||||
if ($value === '-1') {
|
||||
return '0';
|
||||
}
|
||||
$digits = str_split(substr($value, 1));
|
||||
$i = count($digits) - 1;
|
||||
while ($i >= 0) {
|
||||
if ($digits[$i] !== '0') {
|
||||
$digits[$i] = (string) ((int) $digits[$i] - 1);
|
||||
break;
|
||||
}
|
||||
$digits[$i] = '9';
|
||||
$i--;
|
||||
}
|
||||
$imploded = implode('', $digits);
|
||||
if ($imploded[0] === '0') {
|
||||
$imploded = substr($imploded, 1);
|
||||
}
|
||||
|
||||
return '-' . $imploded;
|
||||
}
|
||||
$digits = str_split($value);
|
||||
$carry = 1;
|
||||
for ($i = count($digits) - 1; $i >= 0; $i--) {
|
||||
$sum = (int) $digits[$i] + $carry;
|
||||
$digits[$i] = (string) ($sum % 10);
|
||||
$carry = (int) ($sum / 10);
|
||||
if ($carry === 0) {
|
||||
break;
|
||||
}
|
||||
if ($i === 0) {
|
||||
array_unshift($digits, (string) $carry);
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', $digits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero-padding of two non-negative integers represented in binary form, so that they have the same length.
|
||||
*
|
||||
|
||||
253
vendor/mlocati/ip-lib/src/Service/NumberInChunks.php
vendored
Normal file
253
vendor/mlocati/ip-lib/src/Service/NumberInChunks.php
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
namespace IPLib\Service;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
class NumberInChunks
|
||||
{
|
||||
const CHUNKSIZE_BYTES = 8;
|
||||
|
||||
const CHUNKSIZE_WORDS = 16;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $negative;
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
public $chunks;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $chunkSize;
|
||||
|
||||
/**
|
||||
* @param bool $negative
|
||||
* @param int[] $chunks
|
||||
* @param int $chunkSize
|
||||
*/
|
||||
public function __construct($negative, array $chunks, $chunkSize)
|
||||
{
|
||||
$this->negative = $negative;
|
||||
$this->chunks = $chunks;
|
||||
$this->chunkSize = $chunkSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException if $other has a $chunkSize that's not the same as the $chunkSize of this
|
||||
*
|
||||
* @return \IPLib\Service\NumberInChunks
|
||||
*/
|
||||
public function negate()
|
||||
{
|
||||
return new self($this->chunks === array(0) ? false : !$this->negative, $this->chunks, $this->chunkSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException if $other has a $chunkSize that's not the same as the $chunkSize of this
|
||||
*
|
||||
* @return \IPLib\Service\NumberInChunks
|
||||
*/
|
||||
public function add(NumberInChunks $that)
|
||||
{
|
||||
if ($this->chunkSize !== $that->chunkSize) {
|
||||
throw new InvalidArgumentException('Incompatible chunk size');
|
||||
}
|
||||
if ($this->negative === $that->negative) {
|
||||
return new self($this->negative, self::addChunks($this->chunks, $that->chunks, $this->chunkSize), $this->chunkSize);
|
||||
}
|
||||
if ($that->negative) {
|
||||
list($negative, $chunks) = self::substractChunks($this->chunks, $that->chunks, $this->chunkSize);
|
||||
} else {
|
||||
list($negative, $chunks) = self::substractChunks($that->chunks, $this->chunks, $this->chunkSize);
|
||||
}
|
||||
|
||||
return new self($negative, $chunks, $this->chunkSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $int
|
||||
* @param int $chunkSize
|
||||
*
|
||||
* @return \IPLib\Service\NumberInChunks
|
||||
*/
|
||||
public static function fromInteger($int, $chunkSize)
|
||||
{
|
||||
if ($int === 0) {
|
||||
return new self(false, array(0), $chunkSize);
|
||||
}
|
||||
$negative = $int < 0;
|
||||
if ($negative) {
|
||||
$positiveInt = -$int;
|
||||
if (is_float($positiveInt)) { // -PHP_INT_MIN is bigger than PHP_INT_MAX
|
||||
return self::fromNumericString((string) $int, $chunkSize);
|
||||
}
|
||||
$int = $positiveInt;
|
||||
}
|
||||
$bitMask = (1 << $chunkSize) - 1;
|
||||
$chunks = array();
|
||||
while ($int !== 0) {
|
||||
$chunks[] = $int & $bitMask;
|
||||
$int >>= $chunkSize;
|
||||
}
|
||||
|
||||
return new self($negative, array_reverse($chunks), $chunkSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $numericString a string normalized with BinaryMath::normalizeIntegerString()
|
||||
* @param int $chunkSize
|
||||
*
|
||||
* @return \IPLib\Service\NumberInChunks
|
||||
*/
|
||||
public static function fromNumericString($numericString, $chunkSize)
|
||||
{
|
||||
if ($numericString === '0') {
|
||||
return new self(false, array(0), $chunkSize);
|
||||
}
|
||||
$negative = $numericString[0] === '-';
|
||||
if ($negative) {
|
||||
$numericString = substr($numericString, 1);
|
||||
}
|
||||
$chunks = array();
|
||||
while ($numericString !== '0') {
|
||||
$chunks[] = self::modulo($numericString, $chunkSize);
|
||||
$numericString = self::divide($numericString, $chunkSize);
|
||||
}
|
||||
|
||||
return new self($negative, array_reverse($chunks), $chunkSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $numericString
|
||||
* @param int $chunkSize
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function modulo($numericString, $chunkSize)
|
||||
{
|
||||
$divisor = 1 << $chunkSize;
|
||||
$carry = 0;
|
||||
$len = strlen($numericString);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$digit = (int) $numericString[$i];
|
||||
$carry = ($carry * 10 + $digit) % $divisor;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $numericString
|
||||
* @param int $chunkSize
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function divide($numericString, $chunkSize)
|
||||
{
|
||||
$divisor = 1 << $chunkSize;
|
||||
$quotient = '';
|
||||
$carry = 0;
|
||||
$len = strlen($numericString);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$digit = (int) $numericString[$i];
|
||||
$value = $carry * 10 + $digit;
|
||||
$quotient .= (string) ($value >> $chunkSize);
|
||||
$carry = $value % $divisor;
|
||||
}
|
||||
|
||||
return ltrim($quotient, '0') ?: '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $addend1
|
||||
* @param int[] $addend2
|
||||
* @param int $chunkSize
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
private static function addChunks(array $addend1, array $addend2, $chunkSize)
|
||||
{
|
||||
$divisor = 1 << $chunkSize;
|
||||
$result = array();
|
||||
$carry = 0;
|
||||
while ($addend1 !== array() || $addend2 !== array()) {
|
||||
$sum = $carry + (array_pop($addend1) ?: 0) + (array_pop($addend2) ?: 0);
|
||||
$result[] = $sum % $divisor;
|
||||
$carry = $sum >> $chunkSize;
|
||||
}
|
||||
if ($carry !== 0) {
|
||||
$result[] = $carry;
|
||||
}
|
||||
|
||||
return array_reverse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $minuend
|
||||
* @param int[] $subtrahend
|
||||
* @param int $chunkSize
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function substractChunks(array $minuend, array $subtrahend, $chunkSize)
|
||||
{
|
||||
$minuendCount = count($minuend);
|
||||
$subtrahendCount = count($subtrahend);
|
||||
if ($minuendCount > $subtrahendCount) {
|
||||
$count = $minuendCount;
|
||||
$negative = false;
|
||||
} elseif ($minuendCount < $subtrahendCount) {
|
||||
$count = $subtrahendCount;
|
||||
$negative = true;
|
||||
} else {
|
||||
$count = $minuendCount;
|
||||
$negative = false;
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$delta = $minuend[$i] - $subtrahend[$i];
|
||||
if ($delta === 0) {
|
||||
continue;
|
||||
}
|
||||
if ($delta < 0) {
|
||||
$negative = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($negative) {
|
||||
list($minuend, $subtrahend) = array($subtrahend, $minuend);
|
||||
}
|
||||
$subtrahend = array_pad($subtrahend, -$count, 0);
|
||||
$borrowValue = 1 << $chunkSize;
|
||||
$result = array();
|
||||
$borrow = 0;
|
||||
for ($i = $count - 1; $i >= 0; $i--) {
|
||||
$value = $minuend[$i] - $subtrahend[$i] - $borrow;
|
||||
if ($value < 0) {
|
||||
$value += $borrowValue;
|
||||
$borrow = 1;
|
||||
} else {
|
||||
$borrow = 0;
|
||||
}
|
||||
$result[] = $value;
|
||||
}
|
||||
while (isset($result[1])) {
|
||||
$value = array_pop($result);
|
||||
if ($value !== 0) {
|
||||
$result[] = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array($negative, array_reverse($result));
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class RangesFromBoundaryCalculator
|
||||
*/
|
||||
public function __construct($numBits)
|
||||
{
|
||||
$this->math = new BinaryMath();
|
||||
$this->math = BinaryMath::getInstance();
|
||||
$this->setNumBits($numBits);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user