Overview

Namespaces

  • PHP
  • PHPassLib
    • Application
    • Exception
    • Hash
    • Test
      • Application
      • Hash

Classes

  • Loader
  • Utilities

Interfaces

  • Exception
  • Hash
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * PHP Password Library
  4:  *
  5:  * @package PHPassLib\Utilities
  6:  * @author Ryan Chouinard <rchouinard@gmail.com>
  7:  * @copyright Copyright (c) 2012, Ryan Chouinard
  8:  * @license MIT License - http://www.opensource.org/licenses/mit-license.php
  9:  * @version 3.0.0-dev
 10:  */
 11: 
 12: namespace PHPassLib;
 13: 
 14: use PHPassLib\Exception\InvalidArgumentException;
 15: 
 16: /**
 17:  * Misc. Utilities
 18:  *
 19:  * @package PHPassLib\Utilities
 20:  * @author Ryan Chouinard <rchouinard@gmail.com>
 21:  * @copyright Copyright (c) 2012, Ryan Chouinard
 22:  * @license MIT License - http://www.opensource.org/licenses/mit-license.php
 23:  */
 24: class Utilities
 25: {
 26: 
 27:     const CHARS_H64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
 28: 
 29:     /**
 30:      * Generate a random string of raw bytes.
 31:      *
 32:      * @param integer $count Number of bytes to generate.
 33:      * @return string Random string of raw bytes.
 34:      */
 35:     public static function genRandomBytes($count)
 36:     {
 37:         $count = (int) $count;
 38:         $output = '';
 39: 
 40:         // Try OpenSSL's random generator
 41:         if (function_exists('openssl_random_pseudo_bytes')) {
 42:             // PHP's OpenSSL extension is bugged on Windows for PHP versions
 43:             // prior to 5.3.7.
 44:             if (version_compare(PHP_VERSION, '5.3.7') >= 0 || (PHP_OS & "\xDF\xDF\xDF") !== 'WIN') {
 45:                 $strongCrypto = false;
 46:                 // NOTE: The $strongCrypto argument here isn't telling OpenSSL
 47:                 // to generate (or not) cryptographically secure data. It's
 48:                 // passed by reference, and will be set to true or false after
 49:                 // the function call to indicate whether or not OpenSSL is
 50:                 // confident that the generated data can be used for
 51:                 // cryptographic operations.
 52:                 $output = openssl_random_pseudo_bytes($count, $strongCrypto);
 53:                 if ($strongCrypto && strlen($output) == $count) {
 54:                     return $output;
 55:                 }
 56:             }
 57:         }
 58: 
 59:         // Try mcrypt's interface to the OS CSPRNG
 60:         if (function_exists('mcrypt_create_iv')) {
 61:             $output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
 62:             if (strlen($output) == $count) {
 63:                 return $output;
 64:             }
 65:         }
 66: 
 67:         // Try reading from /dev/urandom, if present
 68:         if (is_readable('/dev/urandom') && ($fh = fopen('/dev/urandom', 'rb'))) {
 69:             if (function_exists('stream_set_read_buffer')) {
 70:                 stream_set_read_buffer($fh, 0);
 71:             }
 72:             $output = fread($fh, $count);
 73:             fclose($fh);
 74:             if (strlen($output) == $count) {
 75:                 return $output;
 76:             }
 77:         }
 78: 
 79:         // Fall back to a locally generated "random" string as last resort
 80:         $randomState = microtime();
 81:         if (function_exists('getmypid')) {
 82:             $randomState .= getmypid();
 83:         }
 84: 
 85:         for ($i = 0; $i < $count; $i += 16) {
 86:             $randomState = md5(microtime() . $randomState);
 87:             $output .= md5($randomState, true);
 88:         }
 89: 
 90:         return substr($output, 0, $count);
 91:     }
 92: 
 93:     /**
 94:      * Encode a string with alternate base64 encoding.
 95:      *
 96:      * @param string $data String to encode.
 97:      * @return string Encoded string.
 98:      */
 99:     public static function altBase64Encode($data)
100:     {
101:         return str_replace(array ('+', '=', "\n"), array ('.', '', ''), base64_encode($data));
102:     }
103: 
104:     /**
105:      * Decode a string which has been encoded with alternate base64 encoding.
106:      *
107:      * @param string $data String to decode.
108:      * @return string Decoded string.
109:      * @throws RuntimeException Throws an InvalidArgumentExceoption if
110:      *     invalid data is passed in.
111:      */
112:     public static function altBase64Decode($data)
113:     {
114:         $data = str_replace('.', '+', $data);
115:         switch (strlen($data) & 0x03) {
116:             case 0:
117:                 return base64_decode($data);
118:             case 2:
119:                 return base64_decode($data . '==');
120:             case 3:
121:                 return base64_decode($data . '=');
122:             default:
123:                 throw new InvalidArgumentException('Invalid data string');
124:         }
125:     }
126: 
127:     /**
128:      * Encode a string.
129:      *
130:      * @param string $bytes String to encode.
131:      * @param string $charset Optional character set used when encoding.
132:      * @return string Encoded string.
133:      */
134:     public static function encode64($bytes, $charset = null)
135:     {
136:         $count = strlen($bytes);
137:         if (!$charset) {
138:             $charset = self::CHARS_H64;
139:         }
140: 
141:         $output = '';
142:         $i = 0;
143:         do {
144:             $value = ord($bytes[$i++]);
145:             $output .= $charset[$value & 0x3f];
146:             if ($i < $count) {
147:                 $value |= ord($bytes[$i]) << 0x08;
148:             }
149:             $output .= $charset[($value >> 0x06) & 0x3f];
150:             if ($i++ >= $count) {
151:                 break;
152:             }
153:             if ($i < $count) {
154:                 $value |= ord($bytes[$i]) << 0x10;
155:             }
156:             $output .= $charset[($value >> 0x0c) & 0x3f];
157:             if ($i++ >= $count) {
158:                 break;
159:             }
160:             $output .= $charset[($value >> 0x12) & 0x3f];
161:         } while ($i < $count);
162: 
163:         return $output;
164:     }
165: 
166:     /**
167:      * Encode a 24-bit integer into a 4-byte string.
168:      *
169:      * @param integer $integer Integer to encode.
170:      * @return string Encoded string.
171:      * @throws InvalidArgumentException Throws an InvalidArgumentException if
172:      *     the supplied argument is not a 24-bit integer.
173:      */
174:     public static function encodeInt24($integer)
175:     {
176:         $integer = (int) $integer;
177:         $chars = self::CHARS_H64;
178: 
179:         if ($integer < 0x00 || $integer > 0xffffff) {
180:             throw new InvalidArgumentException('Integer out of range');
181:         }
182: 
183:         $string  = $chars[$integer & 0x3f];
184:         $string .= $chars[($integer >> 0x06) & 0x3f];
185:         $string .= $chars[($integer >> 0x0c) & 0x3f];
186:         $string .= $chars[($integer >> 0x12) & 0x3f];
187: 
188:         return $string;
189:     }
190: 
191:     /**
192:      * Decodes a 4-byte string into a 24-bit integer.
193:      *
194:      * @param string $string String to decode.
195:      * @return integer Decoded integer.
196:      * @throws InvalidArgumentException Throws an InvalidArgumentException if
197:      *     the supplied argument is not a valid encoded integer.
198:      */
199:     public static function decodeInt24($string)
200:     {
201:         $chars = self::CHARS_H64;
202: 
203:         if (!preg_match('/^[\.\/0-9A-Za-z]{4}$/', $string)) {
204:             throw new InvalidArgumentException('Invalid encoded string');
205:         }
206: 
207:         $integer  = strpos($chars, $string[0]);
208:         $integer += (strpos($chars, $string[1]) << 0x06);
209:         $integer += (strpos($chars, $string[2]) << 0x0c);
210:         $integer += (strpos($chars, $string[3]) << 0x12);
211: 
212:         return $integer;
213:     }
214: 
215: }
216: 
PHP Password Library API documentation generated by ApiGen 2.8.0