Intereting Posts
Информация о потоке PHP в контроллере HTML-экспорт в Excel с использованием JavaScript, работа в FIREFOX, но не в IE и CHROME Как получить доступ к переменным сеанса PHP из функции jQuery в файле .js? cakePHP, возвращающий повторяющиеся записи Как отправить запрос Ajax в среду Laravel 5.0? Библиотека поколения Heatmap для PHP Yii :: t () комплексный перевод с добавлением результатов differenet iva aprameter Доступ к необъявленному статическому свойству: Doctrine \ ODM \ MongoDB \ Mapping \ Driver \ AnnotationDriver :: обработка больших массивов с помощью array_diff установить дату по умолчанию в datepicker только по вторникам и средам? Как создать PDF из HTML с помощью классов начальной загрузки CSS Создать фиксированную длину, не повторяющуюся перестановку большего набора Карты Google – панорамирование и масштабирование по областям – маркеры не появляются при увеличении или панорамировании – ПОМОЩЬ! html5 chunk и webworker ничего не загружают PHP: переписывание URL-адресов

Каков наилучший способ генерации случайного ключа в PHP?

Я ищу создать функцию многократного использования, которая будет генерировать случайный ключ с печатными символами ACSII выбранной длины (от 2 до 1000+). Я думаю, что печатные символы ASCII будут 33-126. Они не обязательно должны быть полностью уникальными, просто уникальными, если они сгенерированы с той же миллисекунды (поэтому uniqid() не будет работать).

Я думаю, что комбинация chr() и mt_rand() может работать.

Это путь, или что-то еще лучший метод?

Изменить: uniqid() также не работает, потому что у него нет параметра длины, это просто то, что дает PHP.

Моя идея : вот что я придумал:

 function GenerateKey($length = 16) { $key = ''; for($i = 0; $i < $length; $i ++) { $key .= chr(mt_rand(33, 126)); } return $key; } 

Есть ли проблемы с этим?

Другое Редактирование. Большинство других вопросов касаются генерации паролей. Я хочу более широкий спектр персонажей, и мне все равно 1 против l . Я хочу, чтобы максимальное количество возможных ключей было возможным.

Примечание: сгенерированный ключ необязательно должен быть криптографически защищен.

Обновление (12/2015): для PHP 7.0 вы должны использовать random_int() вместо mt_rand поскольку он предоставляет «криптографически безопасные значения»,

Лично мне нравится использовать sha1(microtime(true).mt_rand(10000,90000)) но вы ищете больше настраиваемого подхода, поэтому попробуйте эту функцию (которая является модификацией вашего запроса этого ответа ):

 function rand_char($length) { $random = ''; for ($i = 0; $i < $length; $i++) { $random .= chr(mt_rand(33, 126)); } return $random; } 

Тем не менее, это, вероятно, будет значительно медленнее, чем uniqid (), md5 () или sha1 ().

Edit: Похоже, вы добрались до него сначала, извините. : D

Изменить 2: я решил сделать небольшой тест на моей машине Debian с PHP 5 и eAccelerator (извините за длинный код):

 function rand_char($length) { $random = ''; for ($i = 0; $i < $length; $i++) { $random .= chr(mt_rand(33, 126)); } return $random; } function rand_sha1($length) { $max = ceil($length / 40); $random = ''; for ($i = 0; $i < $max; $i ++) { $random .= sha1(microtime(true).mt_rand(10000,90000)); } return substr($random, 0, $length); } function rand_md5($length) { $max = ceil($length / 32); $random = ''; for ($i = 0; $i < $max; $i ++) { $random .= md5(microtime(true).mt_rand(10000,90000)); } return substr($random, 0, $length); } $a = microtime(true); for ($x = 0; $x < 1000; $x++) $temp = rand_char(1000); echo "Rand:\t".(microtime(true) - $a)."\n"; $a = microtime(true); for ($x = 0; $x < 1000; $x++) $temp = rand_sha1(1000); echo "SHA-1:\t".(microtime(true) - $a)."\n"; $a = microtime(true); for ($x = 0; $x < 1000; $x++) $temp = rand_md5(1000); echo "MD5:\t".(microtime(true) - $a)."\n"; 

Результаты:

 Rand: 2.09621596336 SHA-1: 0.611464977264 MD5: 0.618473052979 

Поэтому мое предложение, если вы хотите скорость (но не полную кодировку), – это придерживаться MD5, SHA-1 или Uniqid (которые я еще не тестировал)

Ни один из ответов здесь не достаточен, если вам нужна криптографическая сила случайности (есть ли определенный злоумышленник, пытающийся угадать, каковы ваши случайные ключи?). Хеширование времени небезопасно, злоумышленник может значительно ускорить поиск, угадывая время, в течение которого они думают, что ваш сервер сгенерировал ключ, и легко просматривать все миллисекунды за определенный год, даже на товарном ноутбуке (это 35 битное пространство поиска). Кроме того, опасно опасно предположение просто запустить результаты uniqid() или какого-либо другого слабого случайного источника через хэш-функцию, чтобы «развернуть его», – это не делает поиск злоумышленника более сложным, если они узнают, что вы это сделали.

Если вам действительно нужна криптоуровневая безопасность, вы должны прочитать / dev / random, следующий код должен работать для вас в любой POSIX-совместимой системе (ничего, кроме Windows):

 #Generate a random key from /dev/random function get_key($bit_length = 128){ $fp = @fopen('/dev/random','rb'); if ($fp !== FALSE) { $key = substr(base64_encode(@fread($fp,($bit_length + 7) / 8)), 0, (($bit_length + 5) / 6) - 2); @fclose($fp); return $key; } return null; } 

Если вам нужно немного больше скорости, вы можете читать вместо этого «dev / urandom».

Вы все еще можете использовать uniqid (), просто выполните некоторую дополнительную обработку, чтобы увеличить ее значение до количества символов, которые вам нужны.

Например, чтобы развернуть его до 32 символов, вы можете сделать

 $id = md5(uniqid()); 

Чтобы расширить его до 64 символов, просто добавьте md5 из md5, например

 $first = md5(uniqid()); $id = $first . md5($first); 

Затем, при необходимости, проведите трюк, если вам нужно меньше, чем несколько кратных 32.

Возможно, вы столкнетесь с столкновениями, но это маловероятно. Если вы параноик об этом, просто используйте ту же идею, но uniqid() через симметричный шифр, такой как AES, вместо того, чтобы хэшировать его.

Почему бы не использовать openssl_random_pseudo_bytes http://www.php.net/manual/en/function.openssl-random-pseudo-bytes.php

Мой предыдущий ответ взял хэш uniqid () в сочетании с солью, полученной из системных переменных, но это не генерирует случайный ключ, только тот, который, скорее всего, будет уникальным. Аналогично, вывод из rand () или mt_rand () не является достаточно случайным для криптографических целей.

Чтобы создать случайный ключ, вам нужно перейти к хорошему случайному источнику данных, и функция openssl_random_pseudo_bytes () предназначена для этого:

 $randkey = base64_encode(openssl_random_pseudo_bytes(32)); 

Base64_encode () должен сделать его пригодным для печати.

Причина в том, что другие ответы не рекомендуют openssl_random_pseudo_bytes (), вероятно, это было введено в PHP 5.3, и этот вопрос составляет почти 6 лет.

Вас интересует этот вопрос ?

Я не уверен, почему uniqid() не работает для вас, и в каком случае вам нужен уникальный номер за одну миллисекунду, но не обязательно в противном случае; что вы генерируете так быстро, что в той же миллисекунде вы могли столкнуться? Мне интересно, сколько времени делает uniqid() только для генерации своего номера. Если вы хотите, используйте префиксный параметр функции uniqid() с несколькими случайными буквами, и вы должны быть в безопасности.

Если это для создания файла, вы можете посмотреть tmpfile() или tempname() .

В любом случае, в зависимости от того, чего вы пытаетесь достичь, вы можете просто выполнить цикл и проверить, был ли уже выбран уникальный идентификатор (в массиве, с файлами_файлов и т. Д.) И просто сгенерировать другой, если это так.


Кроме того, поскольку я не уверен, что я точно понимаю ваш вопрос, я бы указал вам на те другие вопросы, которые кажутся похожими, в то время как я получаю разницу:

  • Генерирование (псевдо) случайных буквенно-цифровых строк
  • Сколько случайных элементов перед MD5 вызывает столкновения?

Первый из них будет интересен, если вы хотите сделать уникальный идентификатор, который читается человеком. Второй может быть полезен, если вы хотите играть со случайными числами и md5 / sha1. Хотя, опять же, я думаю, что uniqid() уже может быть тем, что вы ищете.

$ key = md5 (microtime (). rand ());

Microtime сам по себе небезопасен, потому что он оставляет только 1/1000 вероятность угадать.

Ранд сам по себе также не очень безопасен, но хеширование их конкатенации вместе дает довольно солидную рандомизацию.

Также вы можете создать случайный ключ и проверить ключ в своей БД, если ключ завершен, вы можете сгенерировать еще один ключ этим методом

  function activation($lengt=20){ $modalpage =new Modal;//you can call your modal page and check the key $characters = "1234567890abcdefghijklmnopqrstuvwxyz"; for($i=0;$i<$lengt;$i++) { $key .= $characters{rand(0,35)}; $check= array( ":key" => $key, ); $result = $modalpage->findkey($check); if($result==true){ //if the key is exits return the function and generate another key ! return activation($lengt); }else //if the key is not exits return the key return $key; } } $mykey=activation(15);