Skip to content

Instantly share code, notes, and snippets.

@jmwebservices
Created May 7, 2019 02:24
Show Gist options
  • Save jmwebservices/c647ebb3c0fa6b023fd6155c4509f318 to your computer and use it in GitHub Desktop.
Save jmwebservices/c647ebb3c0fa6b023fd6155c4509f318 to your computer and use it in GitHub Desktop.
Create Multibyte Safe Random String (PHP 7+)
<?php
class Str
{
/**
* Generate and return a random string having a specified length and composed of a specified
* set of characters.
*
* <i>This method is multibyte safe.</i>
*
* @param int $length [optional = 32]
* <div>The length of the random string.</div>
*
* @param string $pool [optional]
* <div>List of characters used to generate the random string.</div>
*
* @param string $encoding [optional]
* <div>The encoding of $pool.</div>
*
* @return string
* @throws Str_Exception
*/
public static function random( int $length = 32, string $pool = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', string $encoding = null ) : string
{
if( $length === 0 )
return '';
if( $length < 0 )
throw new Str_Exception( 'Length must be >= 0.' );
if( $pool === '' )
throw new Str_Exception( 'Pool cannot be an empty string.' );
$encoding = $encoding ?? mb_internal_encoding();
$maxKey = mb_strlen( $pool, $encoding );
if( $maxKey === false )
throw new Str_Exception( 'Invalid encoding specified.' );
for( --$maxKey, $random = ''; $length-- ; )
$random .= mb_substr( $pool, random_int( 0, $maxKey ), 1, $encoding );
return $random;
}
}
<?php
class Str_Exception extends Exception{}
<?php
$string = 'a';
$mbString = 'ä';
assert( Str::random( 0 ) === '' );
assert( Str::random( 0, '' ) === '' );
assert( strlen( Str::random( 10 ) ) === 10 );
assert( Str::random( 1, $string ) === $string );
assert( Str::random( 2, $string ) === str_repeat( $string, 2 ) );
assert( Str::random( 1, $mbString ) === $mbString );
assert( Str::random( 2, $mbString ) === str_repeat( $mbString, 2 ) );
try
{
Str::random( -1 );
assert( false, 'Expecting Str_Exception for invalid length.' );
}
catch( Str_Exception $e ){}
try
{
Str::random( 1, '' );
assert( false, 'Expecting Str_Exception for empty pool.' );
}
catch( Str_Exception $e ){}
try
{
@Str::random( 1, $mbString, '' );
assert( false, 'Expecting Str_Exception for invalid encoding.' );
}
catch( Str_Exception $e ){}
@jmwebservices
Copy link
Author

This is a forked version of the fantastic random_str() sample provided by Scott Arciszewski. In particular, it:

  1. Throws for invalid $lengths.
  2. Throws for empty $pools.
  3. Supports multibyte characters in $pool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment