2012-03-18 2 views
2

Я создал функцию в php, которая генерирует хэш из числа (id), и мне нужно проверить, что столкновения не будет (два или более идентификаторов имеют одинаковый хеш). Какую функцию я могу использовать, чтобы проверить, не будет ли столкновений в следующих 99999999 ids? Спасибо!Как проверить хеш-столкновение

+6

петля ......... –

+0

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

+0

@JochenRitzel: Люди всегда, кажется, считают, что по какой-то причине, но это не обязательно так. См. Вопрос [«Функция идеального хэша для кодов удобочитаемого заказа»] (http://stackoverflow.com/q/9551091/978917). (Разумеется, должны быть столкновения, если количество правовых входов больше числа юридических результатов, но если ОП требует только уникальности от 0 до 99999999, то это вряд ли будет иметь место.) – ruakh

ответ

3

Если ваша хеш-функция работает так, как предполагалось, и всегда генерирует один и тот же вывод для одного и того же входа. И ваши входы ограничены номерами 99999999, вы можете просто генерировать хэши для этих чисел и убедиться, что дубликатов нет.

Несмотря на то, что хорошим решением было бы математически продемонстрировать, что ваша хеш-функция будет давать уникальные результаты для этих чисел.

0

Если хеш может быть абсолютно случайным, попробуйте использовать текущую временную метку в нем как дополнительный рандомизатор. Например:

$hash = sha1(microtime() * rand(1, 9999)); 

Вероятность появления дубликата в нем довольно тонкая. Кроме того, попробуйте установить поле базы данных как поле UNIQUE, гарантируя, что дубликат INSERT невозможен. Затем, чтобы сделать вещи завершена, вы можете создать цикл, который пытается, пока это не удается, как так:?

// SHA1 values shouldn't need escaping, but it doesn't really hurt to be extra sure :) 
$query = "INSERT INTO `table` (`hash`) VALUES('" . mysql_real_escape_string($hash) . "')"; 

// Let's try the insert with a max of 10 random hashes 
$tries = 10; 
while(mysql_query($query) !== true) { 
    if($tries <= 0) { 
     break; // Something is really failing, stop trying! 
    } 

    // If this point is reached, apparantly a duplicate was created. Try again. 
    $hash = sha1(microtime() * rand(1, 9999)); 

    // Decrement the tries counter. 
    $tries--; 
} 
+0

Если вы создадите хэш таким образом, вы просто найдете sha1-дайджест случайного числа. Он хочет создать функцию, которая создаст дайджест сообщения из числа, аналогично тому, как работает sha1. И он спрашивает, как он может доказать, что он уникален для конечного диапазона (я думаю) – aurbano

+0

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

Смежные вопросы