PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.2.1
Defender Security – Malware Scanner, Login Security & Firewall v6.2.1
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 / README.md

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

310 lines 13.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 Binary-to-Text Utilities for PHP
2 =================================
3
4 For now, the only class in this repository is **Base2n**.
5
6 Base2n is for binary-to-text conversion with arbitrary encoding schemes that represent binary data in a base 2<sup>
7 n</sup> notation. It can handle non-standard variants of many standard encoding schemes such as [Base64][rfc4648base64]
8 and [Base32][rfc4648base32]. Many binary-to-text encoding schemes use a fixed number of bits of binary data to generate
9 each encoded character. Such schemes generalize to a single algorithm, implemented here.
10
11 [rfc4648base64]: http://tools.ietf.org/html/rfc4648#section-4 "RFC 4648 Base64 Specification"
12
13 [rfc4648base32]: http://tools.ietf.org/html/rfc4648#section-6 "RFC 4648 Base32 Specification"
14
15 Binary-to-text encoding is usually used to represent data in a notation that is safe for transport over text-based
16 protocols, and there are several other practical uses. See the examples below.
17
18
19
20 Basic Base2n Usage
21 ------------------
22
23 With Base2n, you define your encoding scheme parametrically. Let's instantiate a [Base32][rfc4648base32] encoder:
24
25 ```php
26 // RFC 4648 base32 alphabet; case-insensitive
27 $base32 = new Base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
28 $encoded = $base32->encode('encode this');
29 // MVXGG33EMUQHI2DJOM======
30 ```
31
32 ### Constructor Parameters
33
34 - <code>integer $bitsPerCharacter</code> **Required**. The number of bits to use for each encoded character; 1–8. The
35 most practical range is 1–6. The encoding's radix is a power of 2: <code>2^$bitsPerCharacter</code>.
36 1. [base-2, binary][binary]
37 2. [base-4, quaternary][quaternary]
38 3. [base-8, octal][octal]
39 4. [base-16, hexadecimal][hexadecimal]
40 5. [base-32][base32]
41 6. [base-64][base64]
42 7. base-128
43 8. base-256
44
45 [binary]: http://en.wikipedia.org/wiki/Binary_numeral_system "Binary Notation"
46
47 [quaternary]: http://en.wikipedia.org/wiki/Quaternary_numeral_system "Base-2 Notation"
48
49 [octal]: http://en.wikipedia.org/wiki/Octal "Octal Notation"
50
51 [hexadecimal]: http://en.wikipedia.org/wiki/Base16 "Hexadecimal Notation"
52
53 [base32]: http://en.wikipedia.org/wiki/Base32 "Base32 Encoding"
54
55 [base64]: http://en.wikipedia.org/wiki/Base64 "Base64 Encoding"
56
57 - <code>string $chars</code> This string specifies the base alphabet. Must be <code>2^$bitsPerCharacter</code> long.
58 Default: <code>0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_</code>
59
60 - <code>boolean $caseSensitive</code> To decode in a case-sensitive manner. Default: <code>FALSE</code>
61
62 - <code>boolean $rightPadFinalBits</code> How to encode the last character when the bits remaining are fewer than <code>
63 $bitsPerCharacter</code>. When <code>TRUE</code>, the bits to encode are placed in the most significant position of
64 the final group of bits, with the lower bits set to <code>0</code>. When <code>FALSE</code>, the final bits are placed
65 in the least significant position. For [RFC 4648][rfc4648] encodings, <code>$rightPadFinalBits</code>should be <code>
66 TRUE</code>. Default: <code>FALSE</code>
67
68 [rfc4648]: http://tools.ietf.org/html/rfc4648 "RFC 4648: Base16, Base32, Base64"
69
70 - <code>boolean $padFinalGroup</code> It's common to encode characters in groups. For example, Base64 (which is based on
71 6 bits per character) converts 3 raw bytes into 4 encoded characters. If insufficient bytes remain at the end, the
72 final group will be padded with <code>=</code> to complete a group of 4 characters, and the encoded length is always a
73 multiple of 4. Although the information provided by the padding is redundant, some programs rely on it for decoding;
74 Base2n does not. Default: <code>FALSE</code>
75
76 - <code>string $padCharacter</code> When <code>$padFinalGroup</code> is <code>TRUE</code>, this is the pad character
77 used. Default: <code>=</code>
78
79 ### <code>encode()</code> Parameters
80
81 - <code>string $rawString</code> **Required**. The data to be encoded.
82
83 ### <code>decode()</code> Parameters
84
85 - <code>string $encodedString</code> **Required**. The string to be decoded.
86 - <code>boolean $strict</code> When <code>TRUE</code>, <code>NULL</code> will be returned if <code>$encodedString</code>
87 contains an undecodable character. When <code>FALSE</code>, unknown characters are simply ignored. Default: <code>
88 FALSE</code>
89
90 Examples
91 --------
92
93 PHP does not provide any Base32 encoding functions. By setting <code>$bitsPerCharacter</code> to 5 and specifying your
94 desired alphabet in <code>$chars</code>, you can handle any variant of Base32:
95
96 ```php
97 // RFC 4648 base32 alphabet; case-insensitive
98 $base32 = new Base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
99 $encoded = $base32->encode('encode this');
100 // MVXGG33EMUQHI2DJOM======
101 ```
102
103 ```php
104 // RFC 4648 base32hex alphabet
105 $base32hex = new Base2n(5, '0123456789ABCDEFGHIJKLMNOPQRSTUV', FALSE, TRUE, TRUE);
106 $encoded = $base32hex->encode('encode this');
107 // CLN66RR4CKG78Q39EC======
108 ```
109
110 Octal notation:
111
112 ```php
113 $octal = new Base2n(3);
114 $encoded = $octal->encode('encode this');
115 // 312671433366214510072150322711
116 ```
117
118 A convenient way to go back and forth between binary notation and its real binary representation:
119
120 ```php
121 $binary = new Base2n(1);
122 $encoded = $binary->encode('encode this');
123 // 0110010101101110011000110110111101100100011001010010000001110100011010000110100101110011
124 $decoded = $binary->decode($encoded);
125 // encode this
126 ```
127
128 PHP uses a proprietary binary-to-text encoding scheme to generate session identifiers from random hash digests. The most
129 efficient way to store these session IDs in a database is to decode them back to their raw hash digests. PHP's encoding
130 scheme is configured with the <code>[session.hash_bits_per_character][phphashbits]</code> php.ini setting. The decoded
131 size depends on the hash function, set with <code>[session.hash_function][phphash]</code> in php.ini.
132
133 ```php
134 // session.hash_function = 0
135 // session.hash_bits_per_character = 5
136 // 128-bit session ID
137 $sessionId = 'q3c8n4vqpq11i0vr6ucmafg1h3';
138 // Decodes to 16 bytes
139 $phpBase32 = new Base2n(5, '0123456789abcdefghijklmnopqrstuv');
140 $rawSessionId = $phpBase32->decode($sessionId);
141 ```
142
143 ```php
144 // session.hash_function = 1
145 // session.hash_bits_per_character = 6
146 // 160-bit session ID
147 $sessionId = '7Hf91mVc,q-9W1VndNNh3evVN83';
148 // Decodes to 20 bytes
149 $phpBase64 = new Base2n(6, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,');
150 $rawSessionId = $phpBase64->decode($sessionId);
151 ```
152
153 [phphashbits]: http://php.net/manual/en/session.configuration.php#ini.session.hash-bits-per-character "PHP session.hash_bits_per_character"
154
155 [phphash]: http://php.net/manual/en/session.configuration.php#ini.session.hash-function "PHP session.hash_function"
156
157
158 Generate random security tokens:
159
160 ```php
161 $tokenEncoder = new Base2n(6, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,');
162 $binaryToken = openssl_random_pseudo_bytes(32); // PHP >= 5.3
163 $token = $tokenEncoder->encode($binaryToken);
164 // Example: U6M132v9FG-AHhBVaQWOg1gjyUi1IogNxuen0i3u3ep
165 ```
166
167 The rest of these examples are probably more fun than they are practical.
168
169 We can encode arbitrary data with a 7-bit encoding. (Note that this is not the same as
170 the [7bit MIME content-transfer-encoding][7bit].)
171
172 ```php
173 // This uses all 7-bit ASCII characters
174 $base128chars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
175 . "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
176 . "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F"
177 . "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
178 . "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F"
179 . "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F"
180 . "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F"
181 . "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x69\x7A\x7B\x7C\x7D\x7E\x7F";
182
183 $base128 = new Base2n(7, $base128chars);
184 $encoded = $base128->encode('encode this');
185 ```
186
187 [7bit]: http://msdn.microsoft.com/en-us/library/ms526290(v=exchg.10).aspx "7bit MIME Content-Transfer-Encoding"
188
189
190 The following encoding guarantees that the most significant bit is set for every byte:
191
192 ```php
193 // "High" base-128 encoding
194 $high128chars = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
195 . "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
196 . "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
197 . "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF"
198 . "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"
199 . "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF"
200 . "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF"
201 . "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
202
203 $high128 = new Base2n(7, $high128chars);
204 $encoded = $high128->encode('encode this');
205 ```
206
207 Let's create an encoding using exclusively non-printable control characters!
208
209 ```php
210 // Base-32 non-printable character encoding
211 $noPrintChars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
212 . "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
213
214 $nonPrintable32 = new Base2n(5, $noPrintChars);
215 $encoded = $nonPrintable32->encode('encode this');
216 ```
217
218 Why not encode data using only whitespace? Here's a base-4 encoding using space, tab, new line, and carriage return:
219
220 ```php
221 // Base-4 whitespace encoding
222 $whitespaceChars = " \t\n\r";
223
224 $whitespace = new Base2n(2, $whitespaceChars);
225 $encoded = $whitespace->encode('encode this');
226 // "\t\n\t\t\t\n\r\n\t\n \r\t\n\r\r\t\n\t \t\n\t\t \n \t\r\t \t\n\n \t\n\n\t\t\r \r"
227
228 $decoded = $whitespace->decode(
229 "\t\n\t\t\t\n\r\n\t\n \r\t\n\r\r\t\n\t \t\n\t\t \n \t\r\t \t\n\n \t\n\n\t\t\r \r"
230 );
231 // encode this
232 ```
233
234 Counterexamples
235 ----------------
236
237 Base2n is not slow, but it will never outperform an encoding function implemented in C. When one exists, use it instead.
238
239 PHP provides the <code>[base64_encode()][base64_encode]</code> and <code>[base64_decode()][base64_decode]</code>
240 functions, and you should always use them for standard Base64. When you need to use a modified alphabet, you can
241 translate the encoded output with <code>[strtr()][strtr]</code> or <code>[str_replace()][str_replace]</code>.
242
243 [base64_encode]: http://php.net/base64_encode "PHP base64_encode() Function"
244
245 [base64_decode]: http://php.net/base64_decode "PHP base64_decode() Function"
246
247 [strtr]: http://php.net/strtr "PHP strtr() Function"
248
249 [str_replace]: http://php.net/str_replace "PHP str_replace() Function"
250
251 A common variant of Base64 is [modified for URLs and filenames][rfc4648base64url], where <code>+</code>
252 and <code>/</code> are replaced with <code>-</code> and <code>_</code>, and the <code>=</code> padding is omitted. It's
253 better to handle this variant with native PHP functions:
254
255 ```php
256 // RFC 4648 base64url with Base2n...
257 $base64url = new Base2n(6, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', TRUE, TRUE, FALSE);
258 $encoded = $base64url->encode("encode this \xBF\xC2\xBF");
259 // ZW5jb2RlIHRoaXMgv8K_
260
261 // RFC 4648 base64url with native functions...
262 $encoded = str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode("encode this \xBF\xC2\xBF"));
263 // ZW5jb2RlIHRoaXMgv8K_
264 ```
265
266 [rfc4648base64url]: http://tools.ietf.org/html/rfc4648#page-7 "Modified Base64 for URLs"
267
268
269 Native functions get slightly more cumbersome when every position in the alphabet has changed, as seen in this example
270 of [decoding a Bcrypt hash][bmcf]:
271
272 ```php
273 // Decode the salt and digest from a Bcrypt hash
274
275 $hash = '$2y$14$i5btSOiulHhaPHPbgNUGdObga/GC.AVG/y5HHY1ra7L0C9dpCaw8u';
276 $encodedSalt = substr($hash, 7, 22);
277 $encodedDigest = substr($hash, 29, 31);
278
279 // Using Base2n...
280 $bcrypt64 = new Base2n(6, './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', TRUE, TRUE);
281 $rawSalt = $bcrypt64->decode($encodedSalt); // 16 bytes
282 $rawDigest = $bcrypt64->decode($encodedDigest); // 23 bytes
283
284 // Using native functions...
285 $bcrypt64alphabet = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
286 $base64alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
287 $rawSalt = base64_decode(strtr($encodedSalt, $bcrypt64alphabet, $base64alphabet)); // 16 bytes
288 $rawDigest = base64_decode(strtr($encodedDigest, $bcrypt64alphabet, $base64alphabet)); // 23 bytes
289 ```
290
291 [bmcf]: https://github.com/ademarre/binary-mcf "Binary Modular Crypt Format (BMCF)"
292
293 You can encode and decode hexadecimal with <code>[bin2hex()][bin2hex]</code> and <code>[pack()][pack]</code>:
294
295 ```php
296 // Hexadecimal with Base2n...
297 $hexadecimal = new Base2n(4);
298 $encoded = $hexadecimal->encode('encode this'); // 656e636f64652074686973
299 $decoded = $hexadecimal->decode($encoded); // encode this
300
301 // It's better to use native functions...
302 $encoded = bin2hex('encode this'); // 656e636f64652074686973
303 $decoded = pack('H*', $encoded); // encode this
304 // As of PHP 5.4 you can use hex2bin() instead of pack()
305 ```
306
307 [bin2hex]: http://php.net/bin2hex "PHP bin2hex() Function"
308
309 [pack]: http://php.net/pack "PHP pack() Function"
310