| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- <?php
- /**
- * Common String Functions
- *
- * PHP version 5
- *
- * @category Common
- * @package Functions\Strings
- * @author Jim Wigginton <terrafrost@php.net>
- * @copyright 2016 Jim Wigginton
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
- * @link http://phpseclib.sourceforge.net
- */
- // namespace phpseclib\Common\Functions;
- // use phpseclib\Math\BigInteger;
- /**
- * Common String Functions
- *
- * @package Functions\Strings
- * @author Jim Wigginton <terrafrost@php.net>
- */
- abstract class Strings
- {
- /**
- * String Shift
- *
- * Inspired by array_shift
- *
- * @param string $string
- * @param int $index
- * @access public
- * @return string
- */
- public static function shift(&$string, $index = 1)
- {
- $substr = substr($string, 0, $index);
- $string = substr($string, $index);
- return $substr;
- }
- /**
- * String Pop
- *
- * Inspired by array_pop
- *
- * @param string $string
- * @param int $index
- * @access public
- * @return string
- */
- public static function pop(&$string, $index = 1)
- {
- $substr = substr($string, -$index);
- $string = substr($string, 0, -$index);
- return $substr;
- }
- /**
- * Performs blinded equality testing on strings
- *
- * Protects against a particular type of timing attack described.
- *
- * See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)}
- *
- * Thanks for the heads up singpolyma!
- *
- * @access public
- * @param string $x
- * @param string $y
- * @return bool
- */
- public static function equals($x, $y)
- {
- if (strlen($x) != strlen($y)) {
- return false;
- }
- $result = 0;
- for ($i = 0; $i < strlen($x); $i++) {
- $result |= ord($x[$i]) ^ ord($y[$i]);
- }
- return $result == 0;
- }
- /**
- * Parse SSH2-style string
- *
- * Returns either an array or a boolean if $data is malformed.
- *
- * Valid characters for $format are as follows:
- *
- * C = byte
- * b = boolean (true/false)
- * N = uint32
- * s = string
- * i = mpint
- * l = name-list
- *
- * uint64 is not supported.
- *
- * @param string $string
- * @param int $index
- * @access public
- * @return mixed
- */
- public static function unpackSSH2($format, $data)
- {
- $result = array();
- for ($i = 0; $i < strlen($format); $i++) {
- switch ($format[$i]) {
- case 'C':
- case 'b':
- if (!strlen($data)) {
- return false;
- }
- break;
- case 'N':
- case 'i':
- case 's':
- case 'l':
- if (strlen($data) < 4) {
- return false;
- }
- break;
- default:
- throw new \InvalidArgumentException('$format contains an invalid character');
- }
- switch ($format[$i]) {
- case 'C':
- $result[] = ord(self::shift($data));
- continue 2;
- case 'b':
- $result[] = ord(self::shift($data)) != 0;
- continue 2;
- case 'N':
- list(, $temp) = unpack('N', self::shift($data, 4));
- $result[] = $temp;
- continue 2;
- }
- list(, $length) = unpack('N', self::shift($data, 4));
- if (strlen($data) < $length) {
- return false;
- }
- $temp = self::shift($data, $length);
- switch ($format[$i]) {
- case 'i':
- $result[] = new BigInteger($temp, -256);
- break;
- case 's':
- $result[] = $temp;
- break;
- case 'l':
- $result[] = explode(',', $temp);
- }
- }
- return $result;
- }
- /**
- * Create SSH2-style string
- *
- * @param mixed $input..
- * @access public
- * @return mixed
- */
- public static function packSSH2()
- {
- $elements = func_get_args();
- $format = $elements[0];
- array_shift($elements);
- if (strlen($format) != count($elements)) {
- throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string');
- }
- $result = '';
- for ($i = 0; $i < strlen($format); $i++) {
- $element = $elements[$i];
- switch ($format[$i]) {
- case 'C':
- if (!is_int($element)) {
- throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.');
- }
- $result.= pack('C', $element);
- break;
- case 'b':
- if (!is_bool($element)) {
- throw new \InvalidArgumentException('A boolean parameter was expected.');
- }
- $result.= $element ? "\1" : "\0";
- break;
- case 'N':
- if (!is_int($element)) {
- throw new \InvalidArgumentException('An integer was expected.');
- }
- $result.= pack('N', $element);
- break;
- case 's':
- if (!is_string($element)) {
- throw new \InvalidArgumentException('A string was expected.');
- }
- $result.= pack('Na*', strlen($element), $element);
- break;
- case 'i':
- if (!$element instanceof BigInteger) {
- throw new \InvalidArgumentException('A phpseclib\Math\BigInteger object was expected.');
- }
- $element = $element->toBytes(true);
- $result.= pack('Na*', strlen($element), $element);
- break;
- case 'l':
- if (!is_array($element)) {
- throw new \InvalidArgumentException('An array was expected.');
- }
- $element = implode(',', $element);
- $result.= pack('Na*', strlen($element), $element);
- break;
- default:
- throw new \InvalidArgumentException('$format contains an invalid character');
- }
- }
- return $result;
- }
- }
|