PluginProbe
Contact Forms by Cimatti / 1.9.2
Contact Forms by Cimatti v1.9.2
2.3.6 2.3.5 2.3.0 2.2.32 2.2.4 2.2.0 2.1.2 2.1.1 trunk 1.0 1.1 1.2 1.2.1 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 All 62 releases
← All changes | phpseclib-crypt/Hash.php +202 -105 1.4.01.9.2 View file →
@@ -1,6 +1,5 @@
1 1 <?php
2 -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3 2
4 3 /**
5 4 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
6 5 *
@@ -5,22 +4,22 @@
5 4 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
6 5 *
7 6 * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
8 7 *
9 - * md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
8 + * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
10 9 *
11 - * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
10 + * If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
12 11 * the hash. If no valid algorithm is provided, sha1 will be used.
13 12 *
14 13 * PHP versions 4 and 5
15 14 *
16 - * {@internal The variable names are the same as those in
15 + * {@internal The variable names are the same as those in
17 16 * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
18 17 *
19 18 * Here's a short example of how to use this library:
20 19 * <code>
21 20 * <?php
22 - * include('Crypt/Hash.php');
21 + * include 'Crypt/Hash.php';
23 22 *
24 23 * $hash = new Crypt_Hash('sha1');
25 24 *
26 25 * $hash->setKey('abcdefg');
@@ -34,12 +33,12 @@
34 33 * in the Software without restriction, including without limitation the rights
35 34 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36 35 * copies of the Software, and to permit persons to whom the Software is
37 36 * furnished to do so, subject to the following conditions:
38 - *
37 + *
39 38 * The above copyright notice and this permission notice shall be included in
40 39 * all copies or substantial portions of the Software.
41 - *
40 + *
42 41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43 42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44 43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45 44 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
@@ -46,20 +45,19 @@
46 45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47 46 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48 47 * THE SOFTWARE.
49 48 *
50 - * @category Crypt
51 - * @package Crypt_Hash
52 - * @author Jim Wigginton <terrafrost@php.net>
53 - * @copyright MMVII Jim Wigginton
54 - * @license http://www.opensource.org/licenses/mit-license.html MIT License
55 - * @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
56 - * @link http://phpseclib.sourceforge.net
49 + * @category Crypt
50 + * @package Crypt_Hash
51 + * @author Jim Wigginton <terrafrost@php.net>
52 + * @copyright 2007 Jim Wigginton
53 + * @license http://www.opensource.org/licenses/mit-license.html MIT License
54 + * @link http://phpseclib.sourceforge.net
57 55 */
58 56
59 57 /**#@+
60 58 * @access private
61 - * @see Crypt_Hash::Crypt_Hash()
59 + * @see self::Crypt_Hash()
62 60 */
63 61 /**
64 62 * Toggles the internal implementation
65 63 */
@@ -76,19 +74,28 @@
76 74
77 75 /**
78 76 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
79 77 *
78 + * @package Crypt_Hash
80 79 * @author Jim Wigginton <terrafrost@php.net>
81 - * @version 0.1.0
82 80 * @access public
83 - * @package Crypt_Hash
84 81 */
85 -class Crypt_Hash {
82 +class Crypt_Hash
83 +{
86 84 /**
85 + * Hash Parameter
86 + *
87 + * @see self::setHash()
88 + * @var int
89 + * @access private
90 + */
91 + var $hashParam;
92 +
93 + /**
87 94 * Byte-length of compression blocks / key (Internal HMAC)
88 95 *
89 - * @see Crypt_Hash::setAlgorithm()
90 - * @var Integer
96 + * @see self::setAlgorithm()
97 + * @var int
91 98 * @access private
92 99 */
93 100 var $b;
94 101
@@ -94,10 +101,10 @@
94 101
95 102 /**
96 103 * Byte-length of hash output (Internal HMAC)
97 104 *
98 - * @see Crypt_Hash::setHash()
99 - * @var Integer
105 + * @see self::setHash()
106 + * @var int
100 107 * @access private
101 108 */
102 109 var $l = false;
103 110
@@ -103,10 +110,10 @@
103 110
104 111 /**
105 112 * Hash Algorithm
106 113 *
107 - * @see Crypt_Hash::setHash()
108 - * @var String
114 + * @see self::setHash()
115 + * @var string
109 116 * @access private
110 117 */
111 118 var $hash;
112 119
@@ -112,19 +119,28 @@
112 119
113 120 /**
114 121 * Key
115 122 *
116 - * @see Crypt_Hash::setKey()
117 - * @var String
123 + * @see self::setKey()
124 + * @var string
118 125 * @access private
119 126 */
120 127 var $key = false;
121 128
122 129 /**
130 + * Computed Key
131 + *
132 + * @see self::_computeKey()
133 + * @var string
134 + * @access private
135 + */
136 + var $computedKey = false;
137 +
138 + /**
123 139 * Outer XOR (Internal HMAC)
124 140 *
125 - * @see Crypt_Hash::setKey()
126 - * @var String
141 + * @see self::setKey()
142 + * @var string
127 143 * @access private
128 144 */
129 145 var $opad;
130 146
@@ -130,10 +146,10 @@
130 146
131 147 /**
132 148 * Inner XOR (Internal HMAC)
133 149 *
134 - * @see Crypt_Hash::setKey()
135 - * @var String
150 + * @see self::setKey()
151 + * @var string
136 152 * @access private
137 153 */
138 154 var $ipad;
139 155
@@ -139,15 +155,15 @@
139 155
140 156 /**
141 157 * Default Constructor.
142 158 *
143 - * @param optional String $hash
159 + * @param string $hash
144 160 * @return Crypt_Hash
145 161 * @access public
146 162 */
147 - function Crypt_Hash($hash = 'sha1')
163 + function __construct($hash = 'sha1')
148 164 {
149 - if ( !defined('CRYPT_HASH_MODE') ) {
165 + if (!defined('CRYPT_HASH_MODE')) {
150 166 switch (true) {
151 167 case extension_loaded('hash'):
152 168 define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
153 169 break;
@@ -162,32 +178,97 @@
162 178 $this->setHash($hash);
163 179 }
164 180
165 181 /**
182 + * PHP4 compatible Default Constructor.
183 + *
184 + * @see self::__construct()
185 + * @param int $mode
186 + * @access public
187 + */
188 + function Crypt_Hash($hash = 'sha1')
189 + {
190 + $this->__construct($hash);
191 + }
192 +
193 + /**
166 194 * Sets the key for HMACs
167 195 *
168 196 * Keys can be of any length.
169 197 *
170 198 * @access public
171 - * @param String $key
199 + * @param string $key
172 200 */
173 201 function setKey($key = false)
174 202 {
175 203 $this->key = $key;
204 + $this->_computeKey();
176 205 }
177 206
178 207 /**
208 + * Pre-compute the key used by the HMAC
209 + *
210 + * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
211 + * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
212 + *
213 + * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
214 + * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
215 + * every call
216 + *
217 + * @access private
218 + */
219 + function _computeKey()
220 + {
221 + if ($this->key === false) {
222 + $this->computedKey = false;
223 + return;
224 + }
225 +
226 + if (strlen($this->key) <= $this->b) {
227 + $this->computedKey = $this->key;
228 + return;
229 + }
230 +
231 + switch ($mode) {
232 + case CRYPT_HASH_MODE_MHASH:
233 + $this->computedKey = mhash($this->hash, $this->key);
234 + break;
235 + case CRYPT_HASH_MODE_HASH:
236 + $this->computedKey = hash($this->hash, $this->key, true);
237 + break;
238 + case CRYPT_HASH_MODE_INTERNAL:
239 + $this->computedKey = call_user_func($this->hash, $this->key);
240 + }
241 + }
242 +
243 + /**
244 + * Gets the hash function.
245 + *
246 + * As set by the constructor or by the setHash() method.
247 + *
248 + * @access public
249 + * @return string
250 + */
251 + function getHash()
252 + {
253 + return $this->hashParam;
254 + }
255 +
256 + /**
179 257 * Sets the hash function.
180 258 *
181 259 * @access public
182 - * @param String $hash
260 + * @param string $hash
183 261 */
184 262 function setHash($hash)
185 263 {
186 - $hash = strtolower($hash);
264 + $this->hashParam = $hash = strtolower($hash);
187 265 switch ($hash) {
188 266 case 'md5-96':
189 267 case 'sha1-96':
268 + case 'sha256-96':
269 + case 'sha512-96':
270 + $hash = substr($hash, 0, -3);
190 271 $this->l = 12; // 96 / 8 = 12
191 272 break;
192 273 case 'md2':
193 274 case 'md5':
@@ -206,9 +287,28 @@
206 287 $this->l = 64;
207 288 }
208 289
209 290 switch ($hash) {
291 + case 'md2-96':
210 292 case 'md2':
293 + $this->b = 16;
294 + case 'md5-96':
295 + case 'sha1-96':
296 + case 'sha224-96':
297 + case 'sha256-96':
298 + case 'md2':
299 + case 'md5':
300 + case 'sha1':
301 + case 'sha224':
302 + case 'sha256':
303 + $this->b = 64;
304 + break;
305 + default:
306 + $this->b = 128;
307 + }
308 +
309 + switch ($hash) {
310 + case 'md2':
211 311 $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
212 312 CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
213 313 break;
214 314 case 'sha384':
@@ -218,13 +318,12 @@
218 318 default:
219 319 $mode = CRYPT_HASH_MODE;
220 320 }
221 321
222 - switch ( $mode ) {
322 + switch ($mode) {
223 323 case CRYPT_HASH_MODE_MHASH:
224 324 switch ($hash) {
225 325 case 'md5':
226 - case 'md5-96':
227 326 $this->hash = MHASH_MD5;
228 327 break;
229 328 case 'sha256':
230 329 $this->hash = MHASH_SHA256;
@@ -229,17 +328,16 @@
229 328 case 'sha256':
230 329 $this->hash = MHASH_SHA256;
231 330 break;
232 331 case 'sha1':
233 - case 'sha1-96':
234 332 default:
235 333 $this->hash = MHASH_SHA1;
236 334 }
335 + $this->_computeKey();
237 336 return;
238 337 case CRYPT_HASH_MODE_HASH:
239 338 switch ($hash) {
240 339 case 'md5':
241 - case 'md5-96':
242 340 $this->hash = 'md5';
243 341 return;
244 342 case 'md2':
245 343 case 'sha256':
@@ -247,43 +345,38 @@
247 345 case 'sha512':
248 346 $this->hash = $hash;
249 347 return;
250 348 case 'sha1':
251 - case 'sha1-96':
252 349 default:
253 350 $this->hash = 'sha1';
254 351 }
352 + $this->_computeKey();
255 353 return;
256 354 }
257 355
258 356 switch ($hash) {
259 357 case 'md2':
260 - $this->b = 16;
261 - $this->hash = array($this, '_md2');
262 - break;
358 + $this->hash = array($this, '_md2');
359 + break;
263 360 case 'md5':
264 - case 'md5-96':
265 - $this->b = 64;
266 - $this->hash = array($this, '_md5');
267 - break;
361 + $this->hash = array($this, '_md5');
362 + break;
268 363 case 'sha256':
269 - $this->b = 64;
270 - $this->hash = array($this, '_sha256');
271 - break;
364 + $this->hash = array($this, '_sha256');
365 + break;
272 366 case 'sha384':
273 367 case 'sha512':
274 - $this->b = 128;
275 - $this->hash = array($this, '_sha512');
276 - break;
368 + $this->hash = array($this, '_sha512');
369 + break;
277 370 case 'sha1':
278 - case 'sha1-96':
279 371 default:
280 - $this->b = 64;
281 - $this->hash = array($this, '_sha1');
372 + $this->hash = array($this, '_sha1');
282 373 }
283 374
284 375 $this->ipad = str_repeat(chr(0x36), $this->b);
285 376 $this->opad = str_repeat(chr(0x5C), $this->b);
377 +
378 + $this->_computeKey();
286 379 }
287 380
288 381 /**
289 382 * Compute the HMAC.
@@ -288,10 +381,10 @@
288 381 /**
289 382 * Compute the HMAC.
290 383 *
291 384 * @access public
292 - * @param String $text
293 - * @return String
385 + * @param string $text
386 + * @return string
294 387 */
295 388 function hash($text)
296 389 {
297 390 $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
@@ -296,32 +389,26 @@
296 389 {
297 390 $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
298 391
299 392 if (!empty($this->key) || is_string($this->key)) {
300 - switch ( $mode ) {
393 + switch ($mode) {
301 394 case CRYPT_HASH_MODE_MHASH:
302 - $output = mhash($this->hash, $text, $this->key);
395 + $output = mhash($this->hash, $text, $this->computedKey);
303 396 break;
304 397 case CRYPT_HASH_MODE_HASH:
305 - $output = hash_hmac($this->hash, $text, $this->key, true);
398 + $output = hash_hmac($this->hash, $text, $this->computedKey, true);
306 399 break;
307 400 case CRYPT_HASH_MODE_INTERNAL:
308 - /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
309 - resultant L byte string as the actual key to HMAC."
310 -
311 - -- http://tools.ietf.org/html/rfc2104#section-2 */
312 - $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
313 -
314 - $key = str_pad($key, $this->b, chr(0)); // step 1
315 - $temp = $this->ipad ^ $key; // step 2
316 - $temp .= $text; // step 3
317 - $temp = call_user_func($this->hash, $temp); // step 4
318 - $output = $this->opad ^ $key; // step 5
319 - $output.= $temp; // step 6
320 - $output = call_user_func($this->hash, $output); // step 7
401 + $key = str_pad($this->computedKey, $this->b, chr(0)); // step 1
402 + $temp = $this->ipad ^ $key; // step 2
403 + $temp .= $text; // step 3
404 + $temp = call_user_func($this->hash, $temp); // step 4
405 + $output = $this->opad ^ $key; // step 5
406 + $output.= $temp; // step 6
407 + $output = call_user_func($this->hash, $output); // step 7
321 408 }
322 409 } else {
323 - switch ( $mode ) {
410 + switch ($mode) {
324 411 case CRYPT_HASH_MODE_MHASH:
325 412 $output = mhash($this->hash, $text);
326 413 break;
327 414 case CRYPT_HASH_MODE_HASH:
@@ -338,9 +425,9 @@
338 425 /**
339 426 * Returns the hash length (in bytes)
340 427 *
341 428 * @access public
342 - * @return Integer
429 + * @return int
343 430 */
344 431 function getLength()
345 432 {
346 433 return $this->l;
@@ -349,9 +436,9 @@
349 436 /**
350 437 * Wrapper for MD5
351 438 *
352 439 * @access private
353 - * @param String $text
440 + * @param string $m
354 441 */
355 442 function _md5($m)
356 443 {
357 444 return pack('H*', md5($m));
@@ -360,9 +447,9 @@
360 447 /**
361 448 * Wrapper for SHA1
362 449 *
363 450 * @access private
364 - * @param String $text
451 + * @param string $m
365 452 */
366 453 function _sha1($m)
367 454 {
368 455 return pack('H*', sha1($m));
@@ -373,9 +460,9 @@
373 460 *
374 461 * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
375 462 *
376 463 * @access private
377 - * @param String $text
464 + * @param string $m
378 465 */
379 466 function _md2($m)
380 467 {
381 468 static $s = array(
@@ -449,9 +536,9 @@
449 536 *
450 537 * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
451 538 *
452 539 * @access private
453 - * @param String $text
540 + * @param string $m
454 541 */
455 542 function _sha256($m)
456 543 {
457 544 if (extension_loaded('suhosin')) {
@@ -493,8 +580,9 @@
493 580 }
494 581
495 582 // Extend the sixteen 32-bit words into sixty-four 32-bit words
496 583 for ($i = 16; $i < 64; $i++) {
584 + // @codingStandardsIgnoreStart
497 585 $s0 = $this->_rightRotate($w[$i - 15], 7) ^
498 586 $this->_rightRotate($w[$i - 15], 18) ^
499 587 $this->_rightShift( $w[$i - 15], 3);
500 588 $s1 = $this->_rightRotate($w[$i - 2], 17) ^
@@ -499,10 +587,10 @@
499 587 $this->_rightShift( $w[$i - 15], 3);
500 588 $s1 = $this->_rightRotate($w[$i - 2], 17) ^
501 589 $this->_rightRotate($w[$i - 2], 19) ^
502 590 $this->_rightShift( $w[$i - 2], 10);
591 + // @codingStandardsIgnoreEnd
503 592 $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
504 -
505 593 }
506 594
507 595 // Initialize hash value for this chunk
508 596 list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
@@ -554,14 +642,14 @@
554 642 /**
555 643 * Pure-PHP implementation of SHA384 and SHA512
556 644 *
557 645 * @access private
558 - * @param String $text
646 + * @param string $m
559 647 */
560 648 function _sha512($m)
561 649 {
562 650 if (!class_exists('Math_BigInteger')) {
563 - require_once('Math/BigInteger.php');
651 + include_once 'BigInteger.php';
564 652 }
565 653
566 654 static $init384, $init512, $k;
567 655
@@ -567,13 +655,13 @@
567 655
568 656 if (!isset($k)) {
569 657 // Initialize variables
570 658 $init384 = array( // initial values for SHA384
571 - 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
659 + 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
572 660 '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
573 661 );
574 662 $init512 = array( // initial values for SHA512
575 - '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
663 + '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
576 664 '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
577 665 );
578 666
579 667 for ($i = 0; $i < 8; $i++) {
@@ -737,12 +825,12 @@
737 825 /**
738 826 * Right Rotate
739 827 *
740 828 * @access private
741 - * @param Integer $int
742 - * @param Integer $amt
743 - * @see _sha256()
744 - * @return Integer
829 + * @param int $int
830 + * @param int $amt
831 + * @see self::_sha256()
832 + * @return int
745 833 */
746 834 function _rightRotate($int, $amt)
747 835 {
748 836 $invamt = 32 - $amt;
@@ -753,12 +841,12 @@
753 841 /**
754 842 * Right Shift
755 843 *
756 844 * @access private
757 - * @param Integer $int
758 - * @param Integer $amt
759 - * @see _sha256()
760 - * @return Integer
845 + * @param int $int
846 + * @param int $amt
847 + * @see self::_sha256()
848 + * @return int
761 849 */
762 850 function _rightShift($int, $amt)
763 851 {
764 852 $mask = (1 << (32 - $amt)) - 1;
@@ -768,11 +856,11 @@
768 856 /**
769 857 * Not
770 858 *
771 859 * @access private
772 - * @param Integer $int
773 - * @see _sha256()
774 - * @return Integer
860 + * @param int $int
861 + * @see self::_sha256()
862 + * @return int
775 863 */
776 864 function _not($int)
777 865 {
778 866 return ~$int & 0xFFFFFFFF;
@@ -783,12 +871,11 @@
783 871 *
784 872 * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
785 873 * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
786 874 *
787 - * @param String $string
788 - * @param optional Integer $index
789 - * @return String
790 - * @see _sha256()
875 + * @param int $...
876 + * @return int
877 + * @see self::_sha256()
791 878 * @access private
792 879 */
793 880 function _add()
794 881 {
@@ -802,9 +889,19 @@
802 889 foreach ($arguments as $argument) {
803 890 $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
804 891 }
805 892
806 - return fmod($result, $mod);
893 + switch (true) {
894 + case is_int($result):
895 + // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
896 + case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
897 + // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
898 + case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
899 + return fmod($result, $mod);
900 + }
901 +
902 + return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
903 + ((fmod(floor($result / 0x80000000), 2) & 1) << 31);
807 904 }
808 905
809 906 /**
810 907 * String Shift
@@ -810,11 +907,11 @@
810 907 * String Shift
811 908 *
812 909 * Inspired by array_shift
813 910 *
814 - * @param String $string
815 - * @param optional Integer $index
816 - * @return String
911 + * @param string $string
912 + * @param int $index
913 + * @return string
817 914 * @access private
818 915 */
819 916 function _string_shift(&$string, $index = 1)
820 917 {