PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.14.6
Independent Analytics – WordPress Analytics Plugin v2.14.6
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / mlocati / ip-lib / src / Service / UnsignedIntegerMath.php
independent-analytics / vendor / mlocati / ip-lib / src / Service Last commit date
BinaryMath.php 1 year ago RangesFromBoundaryCalculator.php 1 year ago UnsignedIntegerMath.php 1 year ago
UnsignedIntegerMath.php
146 lines
1 <?php
2
3 namespace IAWPSCOPED\IPLib\Service;
4
5 /**
6 * Helper class to work with unsigned integers.
7 *
8 * @internal
9 */
10 class UnsignedIntegerMath
11 {
12 /**
13 * Convert a string containing a decimal, octal or hexadecimal number into its bytes.
14 *
15 * @param string $value
16 * @param int $numBytes the wanted number of bytes
17 * @param bool $onlyDecimal Only parse decimal numbers
18 *
19 * @return int[]|null
20 */
21 public function getBytes($value, $numBytes, $onlyDecimal = \false)
22 {
23 $m = null;
24 if ($onlyDecimal) {
25 if (\preg_match('/^0*(\\d+)$/', $value, $m)) {
26 return $this->getBytesFromDecimal($m[1], $numBytes);
27 }
28 } else {
29 if (\preg_match('/^0[Xx]0*([0-9A-Fa-f]+)$/', $value, $m)) {
30 return $this->getBytesFromHexadecimal($m[1], $numBytes);
31 }
32 if (\preg_match('/^0+([0-7]*)$/', $value, $m)) {
33 return $this->getBytesFromOctal($m[1], $numBytes);
34 }
35 if (\preg_match('/^[1-9][0-9]*$/', $value)) {
36 return $this->getBytesFromDecimal($value, $numBytes);
37 }
38 }
39 // Not a valid number
40 return null;
41 }
42 /**
43 * @return int
44 */
45 protected function getMaxSignedInt()
46 {
47 return \PHP_INT_MAX;
48 }
49 /**
50 * @param string $value never zero-length, never extra leading zeroes
51 * @param int $numBytes
52 *
53 * @return int[]|null
54 */
55 private function getBytesFromBits($value, $numBytes)
56 {
57 $valueLength = \strlen($value);
58 if ($valueLength > $numBytes << 3) {
59 // overflow
60 return null;
61 }
62 $remainderBits = $valueLength % 8;
63 if ($remainderBits !== 0) {
64 $value = \str_pad($value, $valueLength + 8 - $remainderBits, '0', \STR_PAD_LEFT);
65 }
66 $bytes = \array_map('bindec', \str_split($value, 8));
67 return \array_pad($bytes, -$numBytes, 0);
68 }
69 /**
70 * @param string $value may be zero-length, never extra leading zeroes
71 * @param int $numBytes
72 *
73 * @return int[]|null
74 */
75 private function getBytesFromOctal($value, $numBytes)
76 {
77 if ($value === '') {
78 return \array_fill(0, $numBytes, 0);
79 }
80 $bits = \implode('', \array_map(function ($octalDigit) {
81 return \str_pad(\decbin(\octdec($octalDigit)), 3, '0', \STR_PAD_LEFT);
82 }, \str_split($value, 1)));
83 $bits = \ltrim($bits, '0');
84 return $bits === '' ? \array_fill(0, $numBytes, 0) : static::getBytesFromBits($bits, $numBytes);
85 }
86 /**
87 * @param string $value never zero-length, never extra leading zeroes
88 * @param int $numBytes
89 *
90 * @return int[]|null
91 */
92 private function getBytesFromDecimal($value, $numBytes)
93 {
94 $valueLength = \strlen($value);
95 $maxSignedIntLength = \strlen((string) $this->getMaxSignedInt());
96 if ($valueLength < $maxSignedIntLength) {
97 return $this->getBytesFromBits(\decbin((int) $value), $numBytes);
98 }
99 // Divide by two, so that we have 1 less bit
100 $carry = 0;
101 $halfValue = \ltrim(\implode('', \array_map(function ($digit) use(&$carry) {
102 $number = $carry + (int) $digit;
103 $carry = $number % 2 * 10;
104 return (string) $number >> 1;
105 }, \str_split($value, 1))), '0');
106 $halfValueBytes = $this->getBytesFromDecimal($halfValue, $numBytes);
107 if ($halfValueBytes === null) {
108 return null;
109 }
110 $carry = $carry === 0 ? 0 : 1;
111 $result = \array_fill(0, $numBytes, 0);
112 for ($index = $numBytes - 1; $index >= 0; $index--) {
113 $byte = $carry + ($halfValueBytes[$index] << 1);
114 if ($byte <= 0xff) {
115 $carry = 0;
116 } else {
117 $carry = ($byte & ~0xff) >> 8;
118 $byte -= 0x100;
119 }
120 $result[$index] = $byte;
121 }
122 if ($carry !== 0) {
123 // Overflow
124 return null;
125 }
126 return $result;
127 }
128 /**
129 * @param string $value never zero-length, never extra leading zeroes
130 * @param int $numBytes
131 *
132 * @return int[]|null
133 */
134 private function getBytesFromHexadecimal($value, $numBytes)
135 {
136 $valueLength = \strlen($value);
137 if ($valueLength > $numBytes << 1) {
138 // overflow
139 return null;
140 }
141 $value = \str_pad($value, $valueLength + $valueLength % 2, '0', \STR_PAD_LEFT);
142 $bytes = \array_map('hexdec', \str_split($value, 2));
143 return \array_pad($bytes, -$numBytes, 0);
144 }
145 }
146