Будет использование подстроки хеша MD5 как это быть достаточно уникальным?

То, что я пытаюсь сделать, создают 12 символьных идентификаторов для статей о моем веб-сайте, подобном тому, как YouTube обрабатывает их видео идентификатор (http://www.youtube.com/watch?v=53iddd5IcSU). Прямо сейчас я генерирую хеш MD5 и затем захватываю 12 символов его как это:

$ArticleId = substr(MD5("Article".$currentID),10,12)

где $currentID является числовым идентификатором от базы данных (например, 144)

Я немного параноик, что я столкнусь с дублирующимся $ArticleId, но реалистично каковы возможности, что это произойдет? И также, будучи, что столбец в моей базе данных уникален, как я могу обработать этот редкий сценарий, не бросая ужасную ошибку?

P.S. Я сделал маленький сценарий для проверки на дубликаты в первых 5 000$ArticleId's и не было ни одного.

Править: Мне не нравится путь взгляд хешей base64_encode, таким образом, я сделал это:

function retryAID($currentID)
{
    $AID = substr(MD5("Article".$currentID*2),10,12);

    $setAID = "UPDATE `table` SET  `artID` =  '$AID' WHERE `id` = $currentID ";
    mysql_query($setLID) or retryAID($currentID);
}


$AID = substr(MD5("Article".$currentID),10,12);

$setAID = "UPDATE `table` SET  `artID` =  '$AID' WHERE `id` = $currentID ";
mysql_query($setAID) or retryAID($currentID);

Так как столбец AID уникален, mysql_query бросит ошибку, и функция retryAID найдет уникальный идентификатор...

8
задан Atomix 14 February 2010 в 04:49
поделиться

4 ответа

<?php
  function get_id()
  {
    $max = 1679615; // pow(36, 4) - 1;
    $id = '';

    for ($i = 0; $i < 3; ++$i)
    {
      $r = mt_rand(0, $max);
      $id .= str_pad(base_convert($r, 10, 36), 4, "0", STR_PAD_LEFT);
    }
    return $id;
  }
?>

Возвращает 12-значное число в базе 36, что дает 4 738 381 338 321 616 896 возможных вариантов.(Вероятность коллизии зависит от распределения генератора случайных чисел.)

Чтобы гарантировать отсутствие коллизий, вам понадобится цикл:

<?php
do {
  $id = get_id();
} while ( !update_id($id) );
?>
1
ответ дан 5 December 2019 в 21:18
поделиться

Что плохого в использовании последовательного идентификатора? База данных сделает это за вас.

Кроме того, 12 символов по-прежнему остаются 96 битами. 2 96 = 79228162514264337593543950336 возможных хешей. Хотя известно, что MD5 имеет уязвимости к коллизиям, существует огромная разница между вероятностью коллизии и вероятностью того, чтобы ее увидеть.

Обновление:

Исходя из возвращаемого значения функции PHP md5 , которую вы используете, мои цифры выше не совсем верны.

Возвращает хеш в виде 32-значного шестнадцатеричного числа.

Поскольку вы берете 12 символов из 32-значного шестнадцатеричного числа (а не 12 байтов из 128-битного хэша), фактическое количество возможных хэшей, которые вы можете получить, составляет 16 12 = 281474976710656. Еще немало.

6
ответ дан 5 December 2019 в 21:18
поделиться
0
ответ дан 5 December 2019 в 21:18
поделиться

Нет, не очень уникальный.

Почему бы не закодировать его в base64, если он вам нужен короче?

0
ответ дан 5 December 2019 в 21:18
поделиться
Другие вопросы по тегам:

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