ЖЖ от 2004-12-27 14:35:00

Читаю PHP Inside №8. Цитата:

Чтобы узнать, равны ли два файла, можно использовать следующий способ:
if (sha1_file($file) == sha1_file($file2)) { .. }

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

Комментарии 39

Комментарий удалён № 1
bolk автор № 5
Что-то не могу представить ситуацию. Приведи пример.
Комментарий удалён № 27
bolk автор № 32
А, вот ты о чём. Да, в этом случае можно. Поскольку там обычно проверяется существование ошибок. А их обычно немного и они уводят значение хеша чёртзнаеткуда от исходного :)
vladon № 3
математически (т.е. теоретически) — ты прав.

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

а если это сравнение дополнить так:

if ((sha1_file($filename1) == sha1_file($filename2)) && (filesize($filename1) && filesize($filename2))) { .. }

(т.е. сравнивать и длину файлов), то подобрать совпадающие по хэшу, но не равные будет ну очень сложно. интересно посчитать вероятность совпадения… на 1-байтовых файлах вероятность = 0. а дальше — хз.

так что на практике такое можно использовать.
bolk автор № 7
пожалуй, вероятность невелика. Ну и что? Баг, который возникает с ненулевой верояностью — всё равно баг.
mivlad № 8
С ненулевой вероятностью в компьютер может попасть нейтрино высокой энергии и там набедокурить. Однако это никого не беспокоит =)
tony2001 № 9
так же, как и с md5(): все говорят, что совпадение возможно (народ со Спайлога говорил, что них 1 раз совпал md5 на разных данных), но данных так никто и не привел.
а _чисто теоретически_ всё возможно, конечно.
bolk автор № 13
И ты, Брут! от каких данных на spylog брали md5? Посчитай вероятность возникновения дублей на множестве всех файлов от 100 байт до мегабайта, скажем.
valshooter № 11
Ну тогда и пароли криптовать md5 нельзя
bolk автор № 12
Хешировать, ты, наверное, имел ввиду. Неужели ты разницы не видишь? :) Причём, пароли определённой длины не имеют дубликатов после SHA1.
valshooter № 15
md5($pass) — это хеш пароля? тогда хешировать нельзя
bolk автор № 16
ситуация далеко не аналогичная. видимо, всё из-за непонимания самого процесса.

md5($pass) — это хеш пароля. хешировать можно.
1) строки длиной 16 байт и менее не имеют дублей после md5
2) пароли имеют куда более узкий алфавит. т.е. у пароля «мойсуперпароль28748прорукрцлуоке» 256 дублей после md5, но, скорее всего, все они не могут быть введены — потому что совпадения, скорее всего, будут содержать в себе символы, которые не входят в допустимый алфавит. Говоря русским языком, они могут содержать что угодно — \0, \r, \n, \x12 и т.д. Не наберёшь это с клавиатуры.

С файлами ситуация совершенно другая:
1) они могут быть большого размера (мегабайт, например), сколько там дублей сможешь подсчитать?
2) они содержат бинарные данные.
valshooter № 18
bolk, Жень, а md5(какого-либо хеша) — это множество без повторений? т.е. нет двух таких хешей, md5 от которых равны?
bolk автор № 19
valshooter, что такое md5(какого-то хеша)?

если «какого-то хеша» = md5(строка), то md5(«какого-то хеша») <> md5(«какого-то ещё хеша»).

По крайней мере так в теории. Но что это нам даёт? Отвечу сразу: ничего. md5(md5(строка)) и md5(md5(ещё одна строка)) вполне могут совпасть. в том случае, если md5(строка) = md5(ещё одна строка)
valshooter № 20
bolk, Есть два хеша, например:

c4ca4238a0b923820dcc509a6f75849b
c81e728d9d4c2f636f067f89cc14862c

может ли md5('c4ca4238a0b923820dcc509a6f75849b
c81e728d9d4c2f636f067f89cc14862c') == md5('c81e728d9d4c2f636f067f89cc14862c')

я действительно не очень хорошо владею темой.
bolk автор № 21
valshooter, стоп. ничего не понимаю. есть две строки (почему ты их хешами зовёшь?)?

может ли md5(конкатенация этих строк) = md5(одна из строк)? так?

теоритически — могут существовать такие строки. Но, заметь, это не значит, что существует такая строка (ненулевой длины :) ), что прифигачивая её к любой строке и беря от этого md5 мы всегда получаем то же значение, что и md5 этой самой строки.
valshooter № 22
bolk, чёрт, это не конкатенация

имелось в виду md5('c4ca4238a0b923820dcc509a6f75849b') == md5('c81e728d9d4c2f636f067f89cc14862c')

сорри за кривые руки

а хешами — потому что это md5('1') и md5('2') соответственно. или хеш — это не то?
bolk автор № 23
valshooter, теоритически md5 от двух разных строк равной длины, 16 байт или меньше, совпадать не должны. Скорее всего и не совпадают.
valshooter № 24
bolk, Т.е. на множестве строк из 16 байтов md5 — взаимнооднозначная функция?
karim № 26
Вероятность совпадения можно достаточно сократив вычислив и сравнив пары хешей для файлов целиком и нескольких случайных блоков информации внутри файла?
Или же использовать паралельно два различных алгоритма хеширования?
bolk автор № 31
Можно. И в том и другом случае. Но она, на мой взгляд, всё равно будет недостаточно низкой. Мне кажется, можно сравнить sha1 файлов (лучше sha1, а не md5, sha1 длинее), если они совпадут — сравнить их чтением.
azz_kikr № 35
а какую вероятность коллизии можно считать достаточно низкой? :)))))
bolk автор № 36
Как это какую? :) Нулевую
azz_kikr № 37
bolk, вот пример. выбираем произвольно точку из отрезка [0,1]
вероятность выбрать любую точку = 0. и все-таки точка выбирается :))))
(это старый прикол над лебеговой мерой ;))