PHP: будет ли эта функция всегда генерировать уникальную строку? - PullRequest
1 голос
/ 28 июня 2011

Будет ли эта следующая функция всегда генерировать уникальную строку? Каков будет диапазон длины сгенерированной строки из следующей функции? Можно ли его улучшить, чтобы создать больше уникальности?

base_convert(mt_rand(10, 99) . intval(microtime(true) * 100), 8, 36);

Спасибо

Ответы [ 3 ]

4 голосов
/ 28 июня 2011

Имейте в виду, что, как правило, плохая идея писать свои собственные случайные / уникальные функции.Как упоминалось в KingCrunch, PHP имеет встроенную функцию uniqid , которая делает именно то, что вы хотите.

Чтобы ответить на ваш вопрос:

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

длина:

  • mt_rand (10,99): генерируетчисло в диапазоне [10,99] (2 цифры)
  • intval (microtime (true) * 100) получит текущую метку времени Unix плюс 2 цифры миллисекунд.Временная метка (на данный момент) длиной 10 цифр (и будет оставаться таковой около столетия), поэтому общее количество цифр составляет 12 (десятичных) цифр

Затем оно обрабатывает число как base_8число это часто не срабатывает, так как base_8 не знает число 8 или 9 .Я не знаю точное поведение PHP в этом случае, но, тем не менее, оно недопустимо.Если вы действуете так, как число рассматривается как основание 10, у вас возникает следующий вопрос сценария: сколько цифр (основание 36) необходимо для представления чисел между 10 ^ 13 (если mt_rand генерирует 10) и 10 ^ 14 (если mt_rand генерирует 99).

Наименьшее число, для которого base_36 требуется 9 цифр, составляет 2 821 109 907 457, что меньше, чем нижняя граница вашего номера.Однако наибольшее число, которое он может представить с 9 цифрами, составляет 101 559 956 668 416 (~ 10 ^ 14).Таким образом, он сгенерирует 9-значный номер base_36.

[править] Я видел, что вам конкретно нужна уникальная строка из 6 символов.Имейте в виду, что 6 символов относительно короткие, поэтому уникальность трудно гарантировать.Ваша лучшая ставка по-прежнему будет

substr(uniqid(), 0, 6);

Это будет лучше, чем любая функция, которую вам удастся придумать самостоятельно. [/ Edit]

1 голос
/ 28 июня 2011

Простое использование uniqid () хорошая встроенная функция. Это также генерирует уникальный идентификатор из отметки времени. Так что номер всегда будет уникальным.

0 голосов
/ 28 июня 2011

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

function fGetRandomString($vLength = 4) {
    $sRandomString = "";    $sChr = "";
    for ($i = 0 ; $i < $vLength ; $i++) {
        $vState = rand(1, 3);
            switch ($vState)    {
            case 1: $sChr = chr(rand(65, 90));  break;  // CAPS (A-Z)
            case 2: $sChr = chr(rand(97, 122)); break;  // small (a-z)
            case 3: $sChr = chr(rand(48, 57));  break;  // Numbers (0-9)
        }
        if (!in_array($sChr, array('O', 'o', '0', '1', 'l')))   $sRandomString .= $sChr;
        else    $i--;
    }
    return $sRandomString;
}

Удачи!

...