str_shuffle и randomness

Некоторое время назад я написал генератор случайных строк, который строит строку с использованием символа mt_rand () th в строке до тех пор, пока не будет достигнута желаемая длина.

public function getPassword () { if ($this -> password == '') { $pw = ''; $charListEnd = strlen (static::CHARLIST) - 1; for ($loops = mt_rand ($this -> min, $this -> max); $loops > 0; $loops--) { $pw .= substr (static::CHARLIST, mt_rand (0, $charListEnd), 1); } $this -> password = $pw; } return $this -> password; } 

(CHARLIST – это константа класса, содержащая пул символов для пароля. $ Min и $ max являются ограничениями длины)

Сегодня, исследуя что-то еще, я наткнулся на следующий код:

 function generateRandomString ($length = 10) { return substr(str_shuffle ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, $length); } 

Это в значительной степени влияет на мой код цикла mt_rand () в одной строке. Мне очень нравится по этой простой причине, меньшее количество строк кода всегда хорошо. 🙂

Но когда я посмотрел str_shuffle в руководстве PHP, документация на нем была довольно легкой. Одна вещь, которую я действительно хотел узнать, это алгоритм, который он использует для случайности? В руководстве не упоминается, какая рандомизация выполняется для получения перетасованной строки. Если он использует rand () вместо mt_rand (), то, в конце концов, придерживаться моего текущего решения может быть лучше.

Поэтому в основном я хотел бы знать, как str_shuffle рандомизирует строку. Используется ли rand () или mt_rand ()? Я использую свою функцию случайных строк для генерации паролей, поэтому важно качество случайности.

ОБНОВЛЕНИЕ : Как уже указывалось, метод str_shuffle не эквивалентен тому, который я уже использую, и будет менее случайным из-за того, что символы строки остаются такими же, как и вход, только с изменением их порядка. Однако мне все еще интересно, как функция str_shuffle рандомизирует свою входную строку.

Лучшим решением будет mt_rand который использует Mersenne Twister, который намного лучше.

Как уже отмечалось, метод str_shuffle не эквивалентен коду, который я уже использую, и будет менее случайным из-за того, что символы строки остаются такими же, как и вход, только с изменением их порядка. Однако мне все еще интересно, как функция str_shuffle рандомизирует свою входную строку.

Чтобы сделать вывод равным, просто используйте 0,1 и посмотрите на визуальное представление каждой из функций

Простой тестовый код

 header("Content-type: image/png"); $im = imagecreatetruecolor(512, 512) or die("Cannot Initialize new GD image stream"); $white = imagecolorallocate($im, 255, 255, 255); for($y = 0; $y < 512; $y ++) { for($x = 0; $x < 512; $x ++) { if (testMTRand()) { //change each function here imagesetpixel($im, $x, $y, $white); } } } imagepng($im); imagedestroy($im); function testMTRand() { return mt_rand(0, 1); } function testRand() { return rand(0, 1); } function testShuffle() { return substr(str_shuffle("01"), 0, 1); } 

Выход testRand ()

введите описание изображения здесь

Выход testShuffle ()

введите описание изображения здесь

Выходной тестMTRand ()

введите описание изображения здесь

Поэтому в основном я хотел бы знать, как str_shuffle рандомизирует строку. Используется ли rand () или mt_rand ()? Я использую свою функцию случайных строк для генерации паролей, поэтому важно качество случайности.

Вы можете ясно видеть, что str_shuffle производит почти тот же результат, что и rand

Имейте в виду, что этот метод не следует использовать, если ваше приложение действительно сосредоточено на безопасности. Mersenne Twister НЕ криптографически защищен. PRNG может давать значения, которые статистически кажутся случайными, но их легко разбить.

Все еще не криптографически безопасно, но вот способ использования str_shuffle() , позволяя str_shuffle() символ, тем самым улучшая сложность …

 generate_password($length = 8, $strength = 3) { if ($length < 6) $length = 6; if ($length > 32) $length = 32; // Excludes [0,O,o,1,I,i,L,l,1] on purpose for readability $chars = 'abcdefghjkmnpqrstuvwxyz'; if ($strength >= 2) $chars .= '23456789'; if ($strength >= 3) $chars .= strtoupper($lower); if ($strength >= 4) $chars .= '!@#$%&?'; return substr(str_shuffle(str_repeat($chars, $length)), 0, $length); } 

$chars повторяется $length раз до того, как строка перетасовывается, чтобы сделать это немного лучше, чем перетасовать только одно вхождение.

Мы используем это только в системах, которые не хранят конфиденциальную информацию;)