PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / extra / binary-to-text-php / Base2n.php

Base2n.php in Defender Security – Malware Scanner, Login Security & Firewall 6.3.0, at src/extra/binary-to-text-php/Base2n.php

306 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WP_Defender\Extra;
4 /**
5 * Binary-to-text PHP Utilities
6 *
7 * @package binary-to-text-php
8 * @link https://github.com/ademarre/binary-to-text-php
9 * @author Andre DeMarre
10 * @copyright 2009-2013 Andre DeMarre
11 * @license http://opensource.org/licenses/MIT MIT
12 */
13
14 /**
15 * Class for binary-to-text encoding with a base of 2^n
16 *
17 * The Base2n class is for binary-to-text conversion. It employs a
18 * generalization of the algorithms used by many encoding schemes that
19 * use a fixed number of bits to encode each character. In other words,
20 * the base is a power of 2.
21 *
22 * Earlier versions of this class were named
23 * FixedBitNotation and FixedBitEncoding.
24 *
25 * @package binary-to-text-php
26 */
27 class Base2n {
28 protected $_chars;
29 protected $_bitsPerCharacter;
30 protected $_radix;
31 protected $_rightPadFinalBits;
32 protected $_padFinalGroup;
33 protected $_padCharacter;
34 protected $_caseSensitive;
35 protected $_charmap;
36
37 /**
38 * Constructor
39 *
40 * @param integer $bitsPerCharacter Bits to use for each encoded character
41 * @param string $chars Base character alphabet
42 * @param boolean $caseSensitive To decode in a case-sensitive manner
43 * @param boolean $rightPadFinalBits How to encode last character
44 * @param boolean $padFinalGroup Add padding to end of encoded output
45 * @param string $padCharacter Character to use for padding
46 *
47 * @throws InvalidArgumentException for incompatible parameters
48 */
49 public function __construct(
50 $bitsPerCharacter,
51 $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
52 $caseSensitive = true, $rightPadFinalBits = false,
53 $padFinalGroup = false, $padCharacter = '='
54 ) {
55 // Ensure validity of $chars
56 if ( ! is_string( $chars ) || ( $charLength = strlen( $chars ) ) < 2 ) {
57 throw new InvalidArgumentException( '$chars must be a string of at least two characters' );
58 }
59
60 // Ensure validity of $padCharacter
61 if ( $padFinalGroup ) {
62 if ( ! is_string( $padCharacter ) || ! isset( $padCharacter[0] ) ) {
63 throw new InvalidArgumentException( '$padCharacter must be a string of one character' );
64 }
65
66 if ( $caseSensitive ) {
67 $padCharFound = strpos( $chars, $padCharacter[0] );
68 } else {
69 $padCharFound = stripos( $chars, $padCharacter[0] );
70 }
71
72 if ( $padCharFound !== false ) {
73 throw new InvalidArgumentException( '$padCharacter can not be a member of $chars' );
74 }
75 }
76
77 // Ensure validity of $bitsPerCharacter
78 if ( ! is_int( $bitsPerCharacter ) ) {
79 throw new InvalidArgumentException( '$bitsPerCharacter must be an integer' );
80 }
81
82 if ( $bitsPerCharacter < 1 ) {
83 // $bitsPerCharacter must be at least 1
84 throw new InvalidArgumentException( '$bitsPerCharacter can not be less than 1' );
85
86 } elseif ( $charLength < 1 << $bitsPerCharacter ) {
87 // Character length of $chars is too small for $bitsPerCharacter
88 // Find greatest acceptable value of $bitsPerCharacter
89 $bitsPerCharacter = 1;
90 $radix = 2;
91
92 while ( $charLength >= ( $radix <<= 1 ) && $bitsPerCharacter < 8 ) {
93 $bitsPerCharacter ++;
94 }
95
96 $radix >>= 1;
97 throw new InvalidArgumentException(
98 '$bitsPerCharacter can not be more than ' . $bitsPerCharacter
99 . ' given $chars length of ' . $charLength
100 . ' (max radix ' . $radix . ')' );
101
102 } elseif ( $bitsPerCharacter > 8 ) {
103 // $bitsPerCharacter must not be greater than 8
104 throw new InvalidArgumentException( '$bitsPerCharacter can not be greater than 8' );
105
106 } else {
107 $radix = 1 << $bitsPerCharacter;
108 }
109
110 $this->_chars = $chars;
111 $this->_bitsPerCharacter = $bitsPerCharacter;
112 $this->_radix = $radix;
113 $this->_rightPadFinalBits = $rightPadFinalBits;
114 $this->_padFinalGroup = $padFinalGroup;
115 $this->_padCharacter = $padCharacter[0];
116 $this->_caseSensitive = $caseSensitive;
117 }
118
119 /**
120 * Encode a string
121 *
122 * @param string $rawString Binary data to encode
123 *
124 * @return string
125 */
126 public function encode( $rawString ) {
127 // Unpack string into an array of bytes
128 $bytes = unpack( 'C*', $rawString );
129 $byteCount = count( $bytes );
130
131 $encodedString = '';
132 $byte = array_shift( $bytes );
133 $bitsRead = 0;
134 $oldBits = 0;
135
136 $chars = $this->_chars;
137 $bitsPerCharacter = $this->_bitsPerCharacter;
138 $rightPadFinalBits = $this->_rightPadFinalBits;
139 $padFinalGroup = $this->_padFinalGroup;
140 $padCharacter = $this->_padCharacter;
141
142 $charsPerByte = 8 / $bitsPerCharacter;
143 $encodedLength = $byteCount * $charsPerByte;
144
145 // Generate encoded output; each loop produces one encoded character
146 for ( $c = 0; $c < $encodedLength; $c ++ ) {
147
148 // Get the bits needed for this encoded character
149 if ( $bitsRead + $bitsPerCharacter > 8 ) {
150 // Not enough bits remain in this byte for the current character
151 // Save the remaining bits before getting the next byte
152 $oldBitCount = 8 - $bitsRead;
153 $oldBits = $byte ^ ( $byte >> $oldBitCount << $oldBitCount );
154 $newBitCount = $bitsPerCharacter - $oldBitCount;
155
156 if ( ! $bytes ) {
157 // Last bits; match final character and exit loop
158 if ( $rightPadFinalBits ) {
159 $oldBits <<= $newBitCount;
160 }
161 $encodedString .= $chars[ $oldBits ];
162
163 if ( $padFinalGroup ) {
164 // Array of the lowest common multiples of $bitsPerCharacter and 8, divided by 8
165 $lcmMap = array( 1 => 1, 2 => 1, 3 => 3, 4 => 1, 5 => 5, 6 => 3, 7 => 7, 8 => 1 );
166 $bytesPerGroup = $lcmMap[ $bitsPerCharacter ];
167 $pads = $bytesPerGroup * $charsPerByte - ceil( ( strlen( $rawString ) % $bytesPerGroup ) * $charsPerByte );
168 $encodedString .= str_repeat( $padCharacter, $pads );
169 }
170
171 break;
172 }
173
174 // Get next byte
175 $byte = array_shift( $bytes );
176 $bitsRead = 0;
177
178 } else {
179 $oldBitCount = 0;
180 $newBitCount = $bitsPerCharacter;
181 }
182
183 // Read only the needed bits from this byte
184 $bits = $byte >> 8 - ( $bitsRead + ( $newBitCount ) );
185 $bits ^= $bits >> $newBitCount << $newBitCount;
186 $bitsRead += $newBitCount;
187
188 if ( $oldBitCount ) {
189 // Bits come from seperate bytes, add $oldBits to $bits
190 $bits = ( $oldBits << $newBitCount ) | $bits;
191 }
192
193 $encodedString .= $chars[ $bits ];
194 }
195
196 return $encodedString;
197 }
198
199 /**
200 * Decode a string
201 *
202 * @param string $encodedString Data to decode
203 * @param boolean $strict Returns NULL if $encodedString contains an undecodable character
204 *
205 * @return string
206 */
207 public function decode( $encodedString, $strict = false ) {
208 if ( ! $encodedString || ! is_string( $encodedString ) ) {
209 // Empty string, nothing to decode
210 return '';
211 }
212
213 $chars = $this->_chars;
214 $bitsPerCharacter = $this->_bitsPerCharacter;
215 $radix = $this->_radix;
216 $rightPadFinalBits = $this->_rightPadFinalBits;
217 $padFinalGroup = $this->_padFinalGroup;
218 $padCharacter = $this->_padCharacter;
219 $caseSensitive = $this->_caseSensitive;
220
221 // Get index of encoded characters
222 if ( $this->_charmap ) {
223 $charmap = $this->_charmap;
224
225 } else {
226 $charmap = array();
227
228 for ( $i = 0; $i < $radix; $i ++ ) {
229 $charmap[ $chars[ $i ] ] = $i;
230 }
231
232 $this->_charmap = $charmap;
233 }
234
235 // The last encoded character is $encodedString[$lastNotatedIndex]
236 $lastNotatedIndex = strlen( $encodedString ) - 1;
237
238 // Remove trailing padding characters
239 if ( $padFinalGroup ) {
240 while ( $encodedString[ $lastNotatedIndex ] === $padCharacter ) {
241 $encodedString = substr( $encodedString, 0, $lastNotatedIndex );
242 $lastNotatedIndex --;
243 }
244 }
245
246 $rawString = '';
247 $byte = 0;
248 $bitsWritten = 0;
249
250 // Convert each encoded character to a series of unencoded bits
251 for ( $c = 0; $c <= $lastNotatedIndex; $c ++ ) {
252
253 if ( ! $caseSensitive && ! isset( $charmap[ $encodedString[ $c ] ] ) ) {
254 // Encoded character was not found; try other case
255 if ( isset( $charmap[ $cUpper = strtoupper( $encodedString[ $c ] ) ] ) ) {
256 $charmap[ $encodedString[ $c ] ] = $charmap[ $cUpper ];
257
258 } elseif ( isset( $charmap[ $cLower = strtolower( $encodedString[ $c ] ) ] ) ) {
259 $charmap[ $encodedString[ $c ] ] = $charmap[ $cLower ];
260 }
261 }
262
263 if ( isset( $charmap[ $encodedString[ $c ] ] ) ) {
264 $bitsNeeded = 8 - $bitsWritten;
265 $unusedBitCount = $bitsPerCharacter - $bitsNeeded;
266
267 // Get the new bits ready
268 if ( $bitsNeeded > $bitsPerCharacter ) {
269 // New bits aren't enough to complete a byte; shift them left into position
270 $newBits = $charmap[ $encodedString[ $c ] ] << $bitsNeeded - $bitsPerCharacter;
271 $bitsWritten += $bitsPerCharacter;
272
273 } elseif ( $c !== $lastNotatedIndex || $rightPadFinalBits ) {
274 // Zero or more too many bits to complete a byte; shift right
275 $newBits = $charmap[ $encodedString[ $c ] ] >> $unusedBitCount;
276 $bitsWritten = 8; //$bitsWritten += $bitsNeeded;
277
278 } else {
279 // Final bits don't need to be shifted
280 $newBits = $charmap[ $encodedString[ $c ] ];
281 $bitsWritten = 8;
282 }
283
284 $byte |= $newBits;
285
286 if ( $bitsWritten === 8 || $c === $lastNotatedIndex ) {
287 // Byte is ready to be written
288 $rawString .= pack( 'C', $byte );
289
290 if ( $c !== $lastNotatedIndex ) {
291 // Start the next byte
292 $bitsWritten = $unusedBitCount;
293 $byte = ( $charmap[ $encodedString[ $c ] ] ^ ( $newBits << $unusedBitCount ) ) << 8 - $bitsWritten;
294 }
295 }
296
297 } elseif ( $strict ) {
298 // Unable to decode character; abort
299 return null;
300 }
301 }
302
303 return $rawString;
304 }
305 }
306