PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.0.1
Defender Security – Malware Scanner, Login Security & Firewall v3.0.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 3.0.1, at src/extra/binary-to-text-php/README.md

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