PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.11.0
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.11.0
4.11.0 4.10.0 4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Utils / DataEncoder.php
wp-staging / Framework / Utils Last commit date
Cache 1 day ago DBPermissions.php 1 day ago DataEncoder.php 1 day ago DatabaseOptions.php 1 day ago Env.php 1 day ago Escape.php 1 day ago Glob.php 1 day ago Hooks.php 1 day ago Math.php 1 day ago PluginInfo.php 1 day ago Sanitize.php 1 day ago ServerVars.php 1 day ago SlashMode.php 1 day ago Strings.php 1 day ago Times.php 1 day ago Urls.php 1 day ago Version.php 1 day ago WpDefaultDirectories.php 1 day ago
DataEncoder.php
229 lines
1 <?php
2
3 namespace WPStaging\Framework\Utils;
4
5
6
7
8
9 class DataEncoder
10 {
11
12
13
14
15
16 const PACK_MODE_64BIT = 'P';
17
18
19
20
21
22
23 const PACK_MODE_32BIT = 'V';
24
25
26 protected $packMode;
27
28 public function __construct()
29 {
30 $this->packMode = PHP_INT_SIZE === 8 ? self::PACK_MODE_64BIT : self::PACK_MODE_32BIT;
31 }
32
33
34
35
36
37
38 public function intArrayToHex(string $format, array $intArray): string
39 {
40 if (empty($format)) {
41 throw new \InvalidArgumentException('DataEncoder error: Format cannot be empty.');
42 }
43
44 if (empty($intArray)) {
45 throw new \InvalidArgumentException('DataEncoder error: Int array cannot be empty.');
46 }
47
48 $formats = str_split($format);
49 if (count($formats) !== count($intArray)) {
50 throw new \InvalidArgumentException(
51 'DataEncoder error: The number of characters in formats and integers in array must be equal'
52 );
53 }
54
55 if (preg_match('/[^1-8]/', $format)) {
56 throw new \InvalidArgumentException('DataEncoder error: Invalid format.');
57 }
58
59 $index = 0;
60 $result = '';
61 foreach ($formats as $format) {
62
63 try {
64 $bytes = intval($format);
65 if (!is_int($bytes)) {
66 throw new \InvalidArgumentException('DataEncoder error: Invalid format.');
67 }
68
69 $result .= $this->intToHex($intArray[$index], $bytes);
70 } catch (\InvalidArgumentException $ex) {
71 throw new \InvalidArgumentException($ex->getMessage() . ' at index ' . $index);
72 } catch (\Exception $ex) {
73 throw new \InvalidArgumentException($ex->getMessage() . ' at index ' . $index);
74 }
75
76 $index++;
77 }
78
79 return $result;
80 }
81
82
83
84
85
86
87
88
89
90 public function intToHex($value, int $bytes = 8): string
91 {
92 if ($value === null) {
93 throw new \InvalidArgumentException('DataEncoder error: Value cannot be null');
94 }
95
96 if (!is_int($value)) {
97 throw new \InvalidArgumentException('DataEncoder error: Value must be an integer, ' . gettype($value) . ' given');
98 }
99
100 if ($value < 0 && PHP_INT_SIZE === 8) {
101 throw new \InvalidArgumentException('DataEncoder error: Value must be non-negative, ' . $value . ' given');
102 }
103
104 if ($bytes < 1 || $bytes > 8) {
105 throw new \InvalidArgumentException('DataEncoder error: Invalid number of bytes');
106 }
107
108
109 $maxInt = (2 ** ($bytes * 8)) - 1;
110 if ($value > $maxInt) {
111 throw new \InvalidArgumentException('DataEncoder error: Pack: Value is too large for the given number of bytes');
112 }
113
114 $pack = pack($this->packMode, $value);
115
116 if ($bytes <= PHP_INT_SIZE) {
117 return bin2hex(substr($pack, 0, $bytes));
118 }
119
120 $hex = bin2hex($pack);
121
122
123
124 return $hex . str_repeat("00", max(0, $bytes - PHP_INT_SIZE));
125 }
126
127
128
129
130
131
132
133
134 public function hexToIntArray(string $format, string $hex): array
135 {
136 if (empty($format)) {
137 throw new \InvalidArgumentException('DataEncoder error: Format cannot be empty');
138 }
139
140 if (preg_match('/[^1-8]/', $format)) {
141 throw new \InvalidArgumentException('DataEncoder error: Invalid format: ' . $format);
142 }
143
144 if (empty($hex)) {
145 throw new \InvalidArgumentException('DataEncoder error: Hex string cannot be empty');
146 }
147
148 if (strlen($hex) % 2 !== 0) {
149 throw new \InvalidArgumentException('DataEncoder error: Invalid hex string: ' . $hex);
150 }
151
152
153 if (preg_match('/[^0-9a-fA-F]/', $hex)) {
154 throw new \InvalidArgumentException('DataEncoder error: Invalid hex string: ' . $hex);
155 }
156
157 $formats = str_split($format);
158 $index = 0;
159 $intArray = [];
160 foreach ($formats as $format) {
161 $bytes = intval($format);
162 $length = $bytes * 2;
163
164 if ($index + $length > strlen($hex)) {
165 throw new \InvalidArgumentException('DataEncoder error: Hex string is short according to format.');
166 }
167
168 $subHex = substr($hex, $index, $length);
169
170 $intArray[] = $this->hexToInt($subHex, $bytes);
171 $index += $length;
172 }
173
174 if ($index !== strlen($hex)) {
175 throw new \InvalidArgumentException('DataEncoder error: Hex string is long according to format.');
176 }
177
178 return $intArray;
179 }
180
181 public function hexToInt(string $hex, int $bytes = 8): int
182 {
183 if ($bytes < 1 || $bytes > 8) {
184 throw new \InvalidArgumentException('DataEncoder error: Invalid number of bytes.');
185 }
186
187 if (empty($hex)) {
188 throw new \InvalidArgumentException('DataEncoder error: Hex string cannot be empty.');
189 }
190
191 if (strlen($hex) / 2 > $bytes) {
192 throw new \InvalidArgumentException('DataEncoder error: Hex string is longer than the given number of bytes.');
193 }
194
195 if (strlen($hex) % 2 !== 0) {
196 throw new \InvalidArgumentException('DataEncoder error: Invalid hex string: ' . $hex);
197 }
198
199
200 if (preg_match('/[^0-9a-fA-F]/', $hex)) {
201 throw new \InvalidArgumentException('DataEncoder error: Invalid hex string: ' . $hex);
202 }
203
204 $binary = hex2bin($hex);
205 if ($bytes < PHP_INT_SIZE) {
206 $binary = str_pad($binary, PHP_INT_SIZE, "\x00", STR_PAD_RIGHT);
207 }
208
209
210 if ($bytes <= PHP_INT_SIZE) {
211 return unpack($this->packMode, $binary)[1];
212 }
213
214
215
216 $extraData = substr($binary, PHP_INT_SIZE);
217 $extraZero = str_repeat("\x00", max(0, $bytes - PHP_INT_SIZE));
218 if ($extraData !== $extraZero) {
219 throw new \InvalidArgumentException(
220 'DataEncoder error: Unpack: Value is too large for the given number of bytes.'
221 );
222 }
223
224 $dataToUnpack = substr($binary, 0, PHP_INT_SIZE);
225
226 return unpack($this->packMode, $dataToUnpack)[1];
227 }
228 }
229