@@ -532,35 +532,31 @@ public static function tryGetValueInsensitive($key, array $haystack, $default =
532532 *
533533 * See http://tools.ietf.org/html/rfc4122 for more information.
534534 *
535- * Note: This function is available on all platforms, while the
536- * com_create_guid() is only available for Windows.
535+ * Note: See https://stackoverflow.com/a/15875555
537536 *
538537 * @static
539538 *
540539 * @return string A new GUID
541540 */
542541 public static function getGuid ()
543542 {
544- // @codingStandardsIgnoreStart
545-
546- return sprintf (
547- '%04x%04x-%04x-%04x-%02x%02x-%04x%04x%04x ' ,
548- mt_rand (0 , 65535 ),
549- mt_rand (0 , 65535 ), // 32 bits for "time_low"
550- mt_rand (0 , 65535 ), // 16 bits for "time_mid"
551- mt_rand (0 , 4096 ) + 16384 , // 16 bits for "time_hi_and_version", with
552- // the most significant 4 bits being 0100
553- // to indicate randomly generated version
554- mt_rand (0 , 64 ) + 128 , // 8 bits for "clock_seq_hi", with
555- // the most significant 2 bits being 10,
556- // required by version 4 GUIDs.
557- mt_rand (0 , 256 ), // 8 bits for "clock_seq_low"
558- mt_rand (0 , 65535 ), // 16 bits for "node 0" and "node 1"
559- mt_rand (0 , 65535 ), // 16 bits for "node 2" and "node 3"
560- mt_rand (0 , 65535 ) // 16 bits for "node 4" and "node 5"
561- );
543+ $ data = self ::generateCryptoKey (16 );
544+
545+ $ data [6 ] = chr (ord ($ data [6 ]) & 0x0f | 0x40 ); // set version to 0100b = 4
546+ $ data [8 ] = chr (ord ($ data [8 ]) & 0x3f | 0x80 ); // set bits 6-7 to 10
547+
548+ return vsprintf ('%s%s-%s-%s-%s-%s%s%s ' , str_split (bin2hex ($ data ), 4 ));
549+ }
550+
562551
563- // @codingStandardsIgnoreEnd
552+ /**
553+ * Generates a GUID provided a 16 byte pseudo random string
554+ * @param string $data 16 bytes long data string
555+ * @return string A new GUID
556+ */
557+ private static function generateGuid ($ data )
558+ {
559+ return $ guid ;
564560 }
565561
566562 /**
@@ -645,7 +641,59 @@ public static function getEntityId($entity, $type, $method = 'getId')
645641 */
646642 public static function generateCryptoKey ($ length )
647643 {
648- return openssl_random_pseudo_bytes ($ length );
644+ // PHP>=7.0
645+ if (function_exists ('random_bytes ' )) {
646+ return random_bytes ($ length );
647+ }
648+
649+ $ buf = openssl_random_pseudo_bytes ($ length , $ secure );
650+
651+ if ($ buf !== false ) {
652+ return $ buf ;
653+ }
654+
655+ throw new \Exception ('PRNG failure ' );
656+ }
657+
658+ /**
659+ * Fetch a random integer between $min and $max inclusive
660+ * @param int $min
661+ * @param int $max
662+ * @return int
663+ */
664+ public static function generateRandomInt ($ min , $ max )
665+ {
666+ $ range = $ max - $ min ;
667+ $ bits = $ bytes = $ mask = $ val = 0 ;
668+ while ($ range > 0 ) {
669+ if ($ bits % 8 === 0 ) {
670+ ++$ bytes ;
671+ }
672+ ++$ bits ;
673+ $ range >>= 1 ;
674+ $ mask = $ mask << 1 | 1 ;
675+ }
676+ $ valueShift = $ min ;
677+
678+ do {
679+ if ($ attempts > 128 ) {
680+ throw new \Exception ('Could not generate valid random integer ' );
681+ }
682+ $ randomByteString = self ::generateCryptoKey ($ bytes );
683+
684+ $ val = 0 ;
685+ for ($ i = 0 ; $ i < $ bytes ; ++$ i ) {
686+ $ val |= ord ($ randomByteString [$ i ]) << ($ i * 8 );
687+ }
688+
689+ $ val &= $ mask ;
690+ $ val += $ valueShift ;
691+
692+ ++$ attempts ;
693+
694+ } while (!is_int ($ val ) || $ val > $ max || $ val < $ min );
695+
696+ return (int ) $ val ;
649697 }
650698
651699 /**
@@ -673,30 +721,13 @@ public static function ctrCrypt($data, $key, $initializationVector)
673721 sprintf (Resources::INVALID_STRING_LENGTH , 'initializationVector ' , '16 ' )
674722 );
675723
676- $ blockCount = ceil (strlen ($ data ) / 16 );
677-
678- $ ctrData = '' ;
679- for ($ i = 0 ; $ i < $ blockCount ; ++$ i ) {
680- $ ctrData .= $ initializationVector ;
681-
682- // increment Initialization Vector
683- $ j = 15 ;
684- do {
685- $ digit = ord ($ initializationVector [$ j ]) + 1 ;
686- $ initializationVector [$ j ] = chr ($ digit & 0xFF );
687-
688- --$ j ;
689- } while (($ digit == 0x100 ) && ($ j >= 0 ));
690- }
691-
692- $ encryptCtrData = mcrypt_encrypt (
693- MCRYPT_RIJNDAEL_128 ,
724+ return openssl_encrypt (
725+ $ data ,
726+ 'aes-256-ctr ' ,
694727 $ key ,
695- $ ctrData ,
696- MCRYPT_MODE_ECB
728+ OPENSSL_RAW_DATA ,
729+ $ initializationVector
697730 );
698-
699- return $ data ^ $ encryptCtrData ;
700731 }
701732
702733 /**
@@ -720,6 +751,12 @@ public static function base256ToDec($number)
720751 return $ result ;
721752 }
722753
754+ /**
755+ * Replace all hex characters in a string with lowercase
756+ * and URL encode the resulting string.
757+ * @param string $str input string
758+ * @return string URL Encoded string with 00-FF replaced with 00-ff
759+ */
723760 public static function lowerUrlencode ($ str )
724761 {
725762 return preg_replace_callback ('/%[0-9A-F]{2}/ ' ,
0 commit comments