Как создать рандомизированное имя для файла изображения после его изменения [дублировать]

Следующее описание взято из этой страницы :

Метод getElementsByClassName () возвращает коллекцию всех элементов в документе с указанным именем класса, так как объект NodeList.

Объект NodeList представляет собой набор узлов. К узлам можно обращаться по номерам индексов. Индекс начинается с 0.

Совет. Вы можете использовать свойство length объекта NodeList для определения количества элементов с указанным именем класса, затем вы можете прокручивать все элементы и извлекать нужную информацию .

blockquote>

Итак, поскольку параметр getElementsByClassName принимает имя класса.

Если это ваше тело HTML:





то var menuItems = document.getElementsByClassName('menuItem') вернет коллекцию (а не массив) из трех верхних

s, поскольку они соответствуют заданному имени класса.

Затем вы можете перебирать эти узлы (

s в этот случай) с помощью:

for (var menuItemIndex = 0 ; menuItems.length ; menuItemIndex ++) {
   var currentMenuItem = menuItems[menuItemIndex];
   // do stuff with currentMenuItem as a node.
}

Подробнее о различиях между элементами и узлами см. в этой записи .

307
задан hakre 15 April 2012 в 13:15
поделиться

24 ответа

Уведомление о безопасности. Это решение не должно использоваться в ситуациях, когда качество вашей случайности может повлиять на безопасность приложения. В частности, rand() и uniqid() не являются криптографически защищенными генераторами случайных чисел . См. ответ Скотта для безопасной альтернативы.

Если вам не нужно, чтобы он был абсолютно уникальным с течением времени:

md5(uniqid(rand(), true))

В противном случае (если вы уже определили уникальный логин для своего пользователя):

md5(uniqid($your_user_login, true))
242
ответ дан Scott Arciszewski 22 August 2018 в 19:13
поделиться
  • 1
    Оба метода не гарантируют гарантировать уникальность - длина ввода функции md5 больше длины его вывода и в соответствии с en.wikipedia.org/wiki/Pigeonhole_principle коллизия гарантирована. С другой стороны, чем больше население полагается на хеши для достижения "уникальной" id, тем больше вероятность возникновения хотя бы одного столкновения (см. ru.wikipedia.org/wiki/Birthday_problem ). Вероятность может быть крошечной для большинства решений, но она все еще существует. – Dariusz Walczak 14 July 2011 в 13:30
  • 2
    Это не безопасный метод генерации случайных значений. См. Ответ Скотта. – rook 18 September 2013 в 20:51
  • 3
    Для подтверждений электронной почты, которые истекают относительно скоро, я думаю, что крошечная вероятность того, что один человек однажды подтвердит чужой адрес электронной почты, является незначительным риском. Но вы всегда можете проверить, существует ли токен уже в БД после его создания и просто выбрать новый, если это так. Тем не менее, время, затрачиваемое на запись этого фрагмента кода, вероятно, будет потрачено впустую, так как оно, скорее всего, никогда не будет запущено. – Andrew 26 May 2014 в 22:10
  • 4
    Обратите внимание, что md5 возвращает шестнадцатеричные значения, то есть набор символов ограничен [0-9] и [a-f]. – Thijs Riezebeek 15 May 2015 в 16:59
  • 5
    md5 может иметь коллизии, вы просто разрушили uniqid преимущество – user151496 28 September 2016 в 12:42

Для действительно случайных строк вы можете использовать

<?php

echo md5(microtime(true).mt_Rand());

выходы:

40a29479ec808ad4bcff288a48a25d5c

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

0
ответ дан AMB 22 August 2018 в 19:13
поделиться

Это простая функция, которая позволяет создавать случайные строки, содержащие буквы и цифры (буквенно-цифровые). Вы также можете ограничить длину строки. Эти случайные строки могут использоваться для различных целей, в том числе: реферальный код, рекламный код, купонный код. Функция зависит от следующих функций PHP: base_convert, sha1, uniqid, mt_rand

function random_code($length)
{
  return substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, $length);
}

echo random_code(6);

/*sample output
* a7d9e8
* 3klo93
*/
0
ответ дан Arpit J. 22 August 2018 в 19:13
поделиться

Я считаю, что проблема со всеми существующими идеями заключается в том, что они , вероятно, уникальны, но не определенно уникальны (как указано в ответе Дариуша Вальчака на loletech). У меня есть решение, которое на самом деле уникально. Это требует, чтобы ваш скрипт имел какую-то память. Для меня это база данных SQL. Вы также можете просто записать в файл где-нибудь. Существуют две реализации:

Первый метод: имеет два поля, а не 1, которые обеспечивают уникальность. Первое поле - это идентификационный номер, который не является случайным, но является уникальным (первый идентификатор равен 1, второй 2 ...). Если вы используете SQL, просто определите поле ID с свойством AUTO_INCREMENT. Второе поле не является уникальным, но случайным. Это может быть сгенерировано с помощью любых других техник, о которых уже говорили люди. Идея Скотта была хорошей, но md5 удобна и, вероятно, достаточно хороша для большинства целей:

$random_token = md5($_SERVER['HTTP_USER_AGENT'] . time());

Второй метод: в основном та же идея, но изначально выбирает максимальное количество строк, которые когда-либо будут созданы. Это может быть просто очень большое количество, как триллион. Затем сделайте то же самое, сгенерируйте идентификатор, но ноль положите его так, чтобы все идентификаторы имели одинаковое количество цифр. Затем просто конкатенируйте идентификатор со случайной строкой. Это будет достаточно случайным для большинства целей, но раздел ID гарантирует, что он также уникален.

-1
ответ дан bytesized 22 August 2018 в 19:13
поделиться

Я думаю, что это лучший способ использования.

str_shuffle(md5(rand(0,100000)))
0
ответ дан Davinder Kumar 22 August 2018 в 19:13
поделиться

Вы можете использовать UUID (универсальный уникальный идентификатор), он может использоваться для любых целей: от строки аутентификации пользователя до идентификатора транзакции транзакции.

UUID - это 16-октетный (128-разрядный) номер , В своей канонической форме UUID представлен 32 шестнадцатеричными цифрами, отображаемыми в пяти группах, разделенных дефисом, в форме 8-4-4-4-12 для всего 36 символов (32 буквенно-цифровых символа и четыре дефиса).

function generate_uuid() {
    return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
        mt_rand( 0, 0xffff ),
        mt_rand( 0, 0x0C2f ) | 0x4000,
        mt_rand( 0, 0x3fff ) | 0x8000,
        mt_rand( 0, 0x2Aff ), mt_rand( 0, 0xffD3 ), mt_rand( 0, 0xff4B )
    );

}

// вызывая funtion

$transationID = generate_uuid();

, некоторые примерные выходы будут такими:

E302D66D-87E3-4450-8CB6-17531895BF14
22D288BC-7289-442B-BEEA-286777D559F2
51B4DE29-3B71-4FD2-9E6C-071703E1FF31
3777C8C6-9FF5-4C78-AAA2-08A47F555E81
54B91C72-2CF4-4501-A6E9-02A60DCBAE4C
60F75C7C-1AE3-417B-82C8-14D456542CD7
8DE0168D-01D3-4502-9E59-10D665CEBCB2

надеюсь, что это поможет кому-то в будущем :)

20
ответ дан Developer 22 August 2018 в 19:13
поделиться

Я использую этот однострочный слой:

base64_encode(openssl_random_pseudo_bytes(3 * ($length >> 2)));

, где length - длина искомой строки (делится на 4, в противном случае округляется до ближайшего числа, делящегося на 4)

11
ответ дан DudeOnRock 22 August 2018 в 19:13
поделиться
  1. Создайте случайное число с помощью вашего любимого генератора случайных чисел
  2. Умножьте и разделите его, чтобы получить число, соответствующее количеству символов в вашем кодовом алфавите
  3. . Получите пункт в этом индексе в вашем кодовом алфавите.
  4. Повторите с 1) до тех пор, пока у вас не будет желаемой длины

, например (в псевдокоде)

int myInt = random(0, numcharacters)
char[] codealphabet = 'ABCDEF12345'
char random = codealphabet[i]
repeat until long enough
7
ответ дан Erik A. Brandstadmoen 22 August 2018 в 19:13
поделиться

Вот что я использую:

md5(time() . rand());    
// Creates something like 0c947c3b1047334f5bb8a3b7adc1d97b
2
ответ дан Faraz Kelhini 22 August 2018 в 19:13
поделиться

Скотт, да, вы очень хорошо пишете и хорошо решаете! Спасибо.

Мне также требуется создать уникальный токен API для каждого пользователя. Следующим является мой подход, я использовал информацию о пользователе (Userid и Username):

public function generateUniqueToken($userid, $username){

        $rand = mt_rand(100,999);
    $md5 = md5($userid.'!(&^ 532567_465 ///'.$username);

    $md53 = substr($md5,0,3);
    $md5_remaining = substr($md5,3);

    $md5 = $md53. $rand. $userid. $md5_remaining;

    return $md5;
}

Пожалуйста, посмотрите и дайте мне знать, если я могу улучшить какое-либо улучшение. Благодаря

0
ответ дан Himanshu Sharma 22 August 2018 в 19:13
поделиться

Эта функция генерирует случайную клавишу с использованием цифр и букв:

function random_string($length) {
    $key = '';
    $keys = array_merge(range(0, 9), range('a', 'z'));

    for ($i = 0; $i < $length; $i++) {
        $key .= $keys[array_rand($keys)];
    }

    return $key;
}

echo random_string(50);

Пример вывода:

zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8
28
ответ дан Ilmari Karonen 22 August 2018 в 19:13
поделиться
  • 1
    Через некоторое время вы получаете одинаковые номера – Sharpless512 25 February 2014 в 17:31
  • 2
    Это не является полностью случайным, потому что он никогда не будет иметь один и тот же символ более одного раза. – Dwayne 19 December 2014 в 18:32

мы можем использовать эту две строки кода для генерации уникальной строки, протестированной около 10000000 раз итерации

  $sffledStr= str_shuffle('abscdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+');
    $uniqueString = md5(time().$sffledStr);
0
ответ дан IMRA 22 August 2018 в 19:13
поделиться

Вот что я использую в одном из моих проектов, он отлично работает и генерирует UNIQUE RANDOM TOKEN:

$timestampz=time();

function generateRandomString($length = 60) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}


$tokenparta = generateRandomString();


$token = $timestampz*3 . $tokenparta;

echo $token;

Обратите внимание, что я умножил временную метку на три, чтобы создать путаницу для тех, кто мог бы задаться вопросом, как генерируется этот токен;)

Надеюсь, это поможет:)

-1
ответ дан Kaszoni Ferencz 22 August 2018 в 19:13
поделиться
  • 1
    «Обратите внимание, что я умножил временную метку на три, чтобы создать путаницу для тех, кто мог бы задаться вопросом, как генерируется этот токен». Звучит как безопасность через обфускацию stackoverflow.com/questions/533965/… – morph 6 April 2017 в 09:14
  • 2
    – Kaszoni Ferencz 23 October 2018 в 11:17

Вот вам уникальный уникальный генератор идентификаторов. сделанный мной.

<?php
$d=date ("d");
$m=date ("m");
$y=date ("Y");
$t=time();
$dmt=$d+$m+$y+$t;    
$ran= rand(0,10000000);
$dmtran= $dmt+$ran;
$un=  uniqid();
$dmtun = $dmt.$un;
$mdun = md5($dmtran.$un);
$sort=substr($mdun, 16); // if you want sort length code.

echo $mdun;
?>

вы можете повторить любой «var» для своего идентификатора, как вам нравится. но $ mdun лучше, вы можете заменить md5 на sha1 для лучшего кода, но это будет очень долго, что вам может не понадобиться.

Спасибо.

4
ответ дан Krishna Torque 22 August 2018 в 19:13
поделиться
  • 1
    В этом случае случайность гарантируется случайным письменным кодом, верно? – Daniel Kucal 16 January 2016 в 15:27
  • 2
    да, это своего рода "случайный" потому что это нестандартный, неясный код. Это затрудняет прогнозирование ... но на самом деле не использует небезопасные части для генерации случайного числа. поэтому результат технически не случайный или безопасный. – Philipp 5 July 2016 в 18:06

после прочтения предыдущих примеров я придумал следующее:

protected static $nonce_length = 32;

public static function getNonce()
{
    $chars = array();
    for ($i = 0; $i < 10; $i++)
        $chars = array_merge($chars, range(0, 9), range('A', 'Z'));
    shuffle($chars);
    $start = mt_rand(0, count($chars) - self::$nonce_length);
    return substr(join('', $chars), $start, self::$nonce_length);
}

Я дублирую в 10 раз массив [0-9, AZ] и перемешиваю элементы, после того как я получу случайную начальную точку для substr (), чтобы быть более «креативным» :) вы можете добавить [az] и другие элементы в массив, дублировать более или менее, быть более креативными, чем я

0
ответ дан Luiggi ZAMOL 22 August 2018 в 19:13
поделиться
Функция
<?php
function generateRandomString($length = 11) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;

}

?>

выше генерирует случайную строку длиной 11 символов.

0
ответ дан Old Ceylon Mudliar 22 August 2018 в 19:13
поделиться
function random_string($length = 8) {
    $alphabets = range('A','Z');
    $numbers = range('0','9');
    $additional_characters = array('_','=');
    $final_array = array_merge($alphabets,$numbers,$additional_characters);
       while($length--) {
      $key = array_rand($final_array);

      $password .= $final_array[$key];
                        }
  if (preg_match('/[A-Za-z0-9]/', $password))
    {
     return $password;
    }else{
    return  random_string();
    }

 }
1
ответ дан poyynt 22 August 2018 в 19:13
поделиться

Используйте код ниже для генерации случайного числа из 11 символов или изменения номера в соответствии с вашим требованием.

$randomNum=substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 11);

or we can use custom function to generate the random number

 function randomNumber($length){
     $numbers = range(0,9);
     shuffle($numbers);
     for($i = 0;$i < $length;$i++)
        $digits .= $numbers[$i];
     return $digits;
 }

 //generate random number
 $randomNum=randomNumber(11);
5
ответ дан Ramesh Kotkar 22 August 2018 в 19:13
поделиться
  • 1
    Это никогда не может генерировать строку «aaaaaaaaaaa». или "aaaaabbbbbb". Он просто выбирает подстроку случайной перестановки алфавита. Строка длиной 11 символов содержит V (11,35) = 288 возможных значений. Не используйте это, если вы ожидаете, что строки будут уникальными! – Peping 5 September 2017 в 21:55

Я опаздываю, но я здесь с хорошими исследовательскими данными, основанными на функциях, предоставленных ответом Скотта . Таким образом, я установил каплю Digital Ocean только для этого 5-дневного автоматизированного теста и сохранил созданные уникальные строки в базе данных MySQL.

В течение этого периода тестирования я использовал 5 различных длин (5, 10, 15, 20, 50) и +/- 0,5 миллиона записей для каждой длины. Во время моего теста только длина 5 генерировала +/- 3K дубликатов из 0,5 миллиона, а оставшиеся длины не генерировали дубликатов. Таким образом, мы можем сказать, что если мы будем использовать длину 15 или выше с функциями Скотта, тогда мы сможем создать высоконадежные уникальные строки. Вот таблица, показывающая мои исследовательские данные:

Надеюсь, это поможет.

20
ответ дан Rehmat 22 August 2018 в 19:13
поделиться

Мне нравится использовать хеш-ключи при обращении к ссылкам проверки. Я бы рекомендовал использовать microtime и хэширование с использованием MD5, так как не должно быть причин, по которым ключи должны быть одинаковыми, поскольку хеши от микропроцесса.

  1. $key = md5(rand());
  2. $key = md5(microtime());
1
ответ дан René Vogt 22 August 2018 в 19:13
поделиться

Вы можете использовать этот код, я надеюсь, что это будет полезно для вас.

function rand_code($len)
{
 $min_lenght= 0;
 $max_lenght = 100;
 $bigL = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 $smallL = "abcdefghijklmnopqrstuvwxyz";
 $number = "0123456789";
 $bigB = str_shuffle($bigL);
 $smallS = str_shuffle($smallL);
 $numberS = str_shuffle($number);
 $subA = substr($bigB,0,5);
 $subB = substr($bigB,6,5);
 $subC = substr($bigB,10,5);
 $subD = substr($smallS,0,5);
 $subE = substr($smallS,6,5);
 $subF = substr($smallS,10,5);
 $subG = substr($numberS,0,5);
 $subH = substr($numberS,6,5);
 $subI = substr($numberS,10,5);
 $RandCode1 = str_shuffle($subA.$subD.$subB.$subF.$subC.$subE);
 $RandCode2 = str_shuffle($RandCode1);
 $RandCode = $RandCode1.$RandCode2;
 if ($len>$min_lenght && $len<$max_lenght)
 {
 $CodeEX = substr($RandCode,0,$len);
 }
 else
 {
 $CodeEX = $RandCode;
 }
 return $CodeEX;
}

Подробная информация о Генератор случайных кодов в PHP

-1
ответ дан Sajjad Hossain 22 August 2018 в 19:13
поделиться

Я просто искал, как решить эту проблему, но также хочу, чтобы моя функция создавала токен, который также можно использовать для поиска пароля. Это означает, что мне нужно ограничить способность маркера быть угаданным. Поскольку uniqid основано на времени, и согласно php.net «возвращаемое значение мало отличается от microtime ()», uniqid не соответствует критериям. PHP рекомендует использовать openssl_random_pseudo_bytes() вместо этого для генерации криптографически защищенных токенов.

Быстрый, короткий и точечный ответ:

bin2hex(openssl_random_pseudo_bytes($bytes))

, который генерирует случайную строку буквенно-цифровых символов length = $ bytes * 2. К сожалению, у этого есть только алфавит [a-f][0-9], но он работает. Ниже приведена самая сильная функция, которую я мог бы сделать, которая удовлетворяет критериям (это реализованная версия ответа Эрика).

function crypto_rand_secure($min, $max)
{
    $range = $max - $min;
    if ($range < 1) return $min; // not so random...
    $log = ceil(log($range, 2));
    $bytes = (int) ($log / 8) + 1; // length in bytes
    $bits = (int) $log + 1; // length in bits
    $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
    do {
        $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
        $rnd = $rnd & $filter; // discard irrelevant bits
    } while ($rnd > $range);
    return $min + $rnd;
}

function getToken($length)
{
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    $max = strlen($codeAlphabet); // edited

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[crypto_rand_secure(0, $max-1)];
    }

    return $token;
}

crypto_rand_secure($min, $max) работает как сокращение замены для rand() или mt_rand , Он использует openssl_random_pseudo_bytes, чтобы создать случайное число между $ min и $ max.

getToken($length) создает алфавит для использования в токене, а затем создает строку длины $length.

EDIT: Я пренебрег ссылкой на источник - http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322 ]

EDIT (PHP7): С выпуском PHP7 стандартная библиотека теперь имеет две новые функции, которые могут заменить / улучшить / упростить функцию crypto_rand_secure выше. random_bytes($length) и random_int($min, $max)

http://php.net/manual/en/function.random-bytes.php

http://php.net/manual/en/function.random-int.php

Пример:

function getToken($length){
     $token = "";
     $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
     $codeAlphabet.= "0123456789";
     $max = strlen($codeAlphabet); // edited

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[random_int(0, $max-1)];
    }

    return $token;
}
402
ответ дан Scott 22 August 2018 в 19:13
поделиться
  • 1
    Согласовано. Хранилище паролей с обычным текстом ужасно! (Я использую blowfish.) Но после того, как токен сгенерирован, он позволяет держателю токена сбросить пароль, поэтому токен эквивалентен паролю, пока он действителен (и рассматривается как таковой). – Scott 8 May 2013 в 02:44
  • 2
    Привет, я объединил ваш отличный код с удобной функциональностью метода Kohana Text :: random () и создал этот метод: gist.github.com/raveren/5555297 – raveren 10 May 2013 в 16:51
  • 3
    Отлично! Я тестировал его с длиной 10 символов. 100000 токенов и до сих пор нет дубликатов! – Sharpless512 26 February 2014 в 10:13
  • 4
    Я использовал этот процесс и нашел его очень медленным. При длине 36 он был отключен на сервере dev. При длине 24 это продолжалось около 30 секунд. Не уверен, что я сделал не так, но это было слишком медленно для меня, и я выбрал другое решение. – Shane 17 April 2014 в 02:25
  • 5
    Вы также можете использовать base64_encode вместо bin2hex, чтобы получить более короткую строку с большим алфавитом. – erjiang 30 May 2014 в 14:57

Объектно-ориентированная версия наиболее разрешенного решения

Я создал объектно-ориентированное решение, основанное на ответе Скотта:

<?php

namespace Utils;

/**
 * Class RandomStringGenerator
 * @package Utils
 *
 * Solution taken from here:
 * http://stackoverflow.com/a/13733588/1056679
 */
class RandomStringGenerator
{
    /** @var string */
    protected $alphabet;

    /** @var int */
    protected $alphabetLength;


    /**
     * @param string $alphabet
     */
    public function __construct($alphabet = '')
    {
        if ('' !== $alphabet) {
            $this->setAlphabet($alphabet);
        } else {
            $this->setAlphabet(
                  implode(range('a', 'z'))
                . implode(range('A', 'Z'))
                . implode(range(0, 9))
            );
        }
    }

    /**
     * @param string $alphabet
     */
    public function setAlphabet($alphabet)
    {
        $this->alphabet = $alphabet;
        $this->alphabetLength = strlen($alphabet);
    }

    /**
     * @param int $length
     * @return string
     */
    public function generate($length)
    {
        $token = '';

        for ($i = 0; $i < $length; $i++) {
            $randomKey = $this->getRandomInteger(0, $this->alphabetLength);
            $token .= $this->alphabet[$randomKey];
        }

        return $token;
    }

    /**
     * @param int $min
     * @param int $max
     * @return int
     */
    protected function getRandomInteger($min, $max)
    {
        $range = ($max - $min);

        if ($range < 0) {
            // Not so random...
            return $min;
        }

        $log = log($range, 2);

        // Length in bytes.
        $bytes = (int) ($log / 8) + 1;

        // Length in bits.
        $bits = (int) $log + 1;

        // Set all lower bits to 1.
        $filter = (int) (1 << $bits) - 1;

        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));

            // Discard irrelevant bits.
            $rnd = $rnd & $filter;

        } while ($rnd >= $range);

        return ($min + $rnd);
    }
}

Использование

<?php

use Utils\RandomStringGenerator;

// Create new instance of generator class.
$generator = new RandomStringGenerator;

// Set token length.
$tokenLength = 32;

// Call method to generate random string.
$token = $generator->generate($tokenLength);

Пользовательский алфавит

При необходимости вы можете использовать произвольный алфавит. Просто передайте строку с поддерживаемыми символами в конструктор или сеттер:

<?php

$customAlphabet = '0123456789ABCDEF';

// Set initial alphabet.
$generator = new RandomStringGenerator($customAlphabet);

// Change alphabet whenever needed.
$generator->setAlphabet($customAlphabet);

Вот выходные образцы

SRniGU2sRQb2K1ylXKnWwZr4HrtdRgrM
q1sRUjNq1K9rG905aneFzyD5IcqD4dlC
I0euIWffrURLKCCJZ5PQFcNUCto6cQfD
AKwPJMEM5ytgJyJyGqoD5FQwxv82YvMr
duoRF6gAawNOEQRICnOUNYmStWmOpEgS
sdHUkEn4565AJoTtkc8EqJ6cC4MLEHUx
eVywMdYXczuZmHaJ50nIVQjOidEVkVna
baJGt7cdLDbIxMctLsEBWgAw5BByP5V0
iqT0B2obq3oerbeXkDVLjZrrLheW4d8f
OUQYCny6tj2TYDlTuu1KsnUyaLkeObwa

Надеюсь, это поможет кому-то. Ура!

83
ответ дан Slava Fomin II 22 August 2018 в 19:13
поделиться
  • 1
    Извините, но как я могу запустить эту вещь? Я сделал $obj = new RandomStringGenerator;, но какой метод мне следует вызвать? Спасибо. – sg552 1 October 2014 в 17:41
  • 2
    @ sg552, вы должны вызвать метод generate, как в примере выше. Просто передайте ему целое число, чтобы указать длину результирующей строки. – Slava Fomin II 2 December 2014 в 09:38
  • 3
    Спасибо, что это работает для меня, но Custom Alphabet этого не сделал. Я получаю пустой вывод, когда я эхо. Во всяком случае, я даже не уверен, что использует второй пример Custom Alphabet, поэтому я думаю, что просто останусь с первым примером. Благодарю. – sg552 3 December 2014 в 22:24
  • 4
    Приятно, но довольно сильно, в большинстве сценариев, если ваш проект сильно зависит от случайно генерируемых кодов – dspacejs 8 May 2015 в 11:47
  • 5
    да приятный, но излишний, особенно учитывая, что теперь он довольно устарел для php 5.7 – Andrew 21 March 2016 в 18:30

Упрощение кода Скотта выше, удалив ненужные циклы, которые сильно замедляются и не делают его более безопасным, чем вызов openssl_random_pseudo_bytes только один раз

function crypto_rand_secure($min, $max)
{
 $range = $max - $min;
 if ($range < 1) return $min; // not so random...
 $log = ceil(log($range, 2));
 $bytes = (int) ($log / 8) + 1; // length in bytes
 $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
 return $min + $rnd%$range;
}

function getToken($length)
{
 return bin2hex(openssl_random_pseudo_bytes($length)
}
-2
ответ дан yumoji 22 August 2018 в 19:13
поделиться
  • 1
    К сожалению, я не могу согласиться с вами, что это подходящее упрощение функции crypto_rand_secure. Цикл необходим, чтобы избежать смещения по модулю, которое возникает, когда вы принимаете результат произвольно сгенерированного числа, а затем меняете его числом, которое делит диапазон. en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Modulo_bias . Используя цикл, чтобы выкинуть любые числа за пределами диапазона и выбирая новый номер, он избегает этого смещения. stackoverflow.com/questions/10984974/… – Scott 2 June 2016 в 12:44
  • 2
    @Scott, это сообщение о rand (). Однако в этом случае он уже позабочен openssl_random_pseudo_bytes, поэтому цикл не нужен. – yumoji 2 June 2016 в 13:53
  • 3
    gist.github.com/anonymous/87e3ae6fd3320447f46b973e75c2ea85 - Запустите этот скрипт. Вы увидите, что распределение результатов не является случайным. Числа между 0-55 имеют более высокий показатель, чем числа между 56-100. openssl не вызывает этого, это из-за погрешности по модулю в вашем возвращении. 100 (диапазон) не делит 255 (1 байт) равномерно и вызывает эти результаты. Моя самая большая проблема с вашим ответом заключается в том, что вы заявляете, что функция такая же безопасная, как использование цикла, что является ложным. Ваша реализация crypto_rand_secure не является криптографически безопасной и вводит в заблуждение. – Scott 2 June 2016 в 15:08
  • 4
    @Scott, мы отвлекаемся здесь, это не про последний оператор return, он также может быть постепенно вычисляться из возвращаемого значения openssl_random_pseudo_bytes без использования modulo. То, что я делаю, состоит в том, что цикл не нужен, как только openssl_random_pseudo_bytes возвращает случайные байты. Сделав цикл, вы не сделаете его более безопасным, просто сделав его медленным. – yumoji 2 June 2016 в 16:13
  • 5
    Этот ответ распространяет плохую информацию. Вы правы, что цикл не делает openssl более безопасным, но, что более важно, он не делает его менее безопасным, этот ответ делает. Приведенный выше код имеет совершенно хорошее случайное число и искажает его, смещая его на более низкие цифры. Если вы ответили на свой ответ, указав, что это быстрее (путем удаления цикла), но это не CSPRNG, это решит эту проблему. Пожалуйста, для любви к крипто, сообщите пользователям, что выход этой функции может быть смещен и not эквивалентное решение. Цикл не просто раздражает вас. – Scott 2 June 2016 в 17:44
Другие вопросы по тегам:

Похожие вопросы: