URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7083
[ Назад ]

Исходное сообщение
"Создание хешей файлов"

Отправлено weldpua2008 , 04-Янв-08 23:53 
Привет всем
Цель - читаем файл и создаем для него уникальный хеш, что бы можно было даже в случае переименования получить такой же хеш.
Уже есть такие утилитки как md5sum, shaXXXsum ...
но проблема в том что файл на 4Гб у меня для md5sum отдает хеш за ~3m, sha1sum за ~5m
А Мне нужно очень быстро. Планируется получать хеши для видео файлов, образов дисков и т.д. Размер от 1Мб до 16Гб. Использование md5sum и т.д. - очень долго, мне бы что-то что читало бы несколько мелких частей (от 128Кб до 1Мб каждая например) файла из начала середины конца и конца например что то типа:
./supercat file.avi| md5sum

Помогите ПЛЗ


Содержание

Сообщения в этом обсуждении
"Создание хешей файлов"
Отправлено anonymous , 05-Янв-08 00:07 
Можно сделать то, что вы хотите -- посчитать хеш только по некоторым блокам.  Но тогда хеш не будет уникальным.  Допустим у вас есть файл:

XXXXXAAAAAAAAAAAAAAAAAXXXXXXAAAAAAAAAAAAAAAAXXXXXX

Буквами X обозначены те блоки, которые включены в хеш.  Тогда те блоки, которые обозначены буквой A можно произвольно менять, и хеш не изменится.

Так что этот метод не подходит не только для криптогафических применений, но и для отслеживания изменений файлов.  Для глобальной идентификации файлов по всему миру он тоже не подходит.  Тут лучше посмотрите в строну хешей в сети edonkey.  Большой плюс -- они уже посчитаны для миллионов файлов и подходят не только для "идентификации"... =)

А вот если вы просто хотите создать некоторую маленькую строку, которой потом будете идентифицировать файл локально -- например, при добавлении файла в фильмотеку для него создаётся такой хеш, который служет идентификатором каким-то -- ваша схема вполне подходит.  Только тут лучше не изобретать велосипед, и использовать UUID, потому что для работы с ним уже много готовых библиотек есть.  Да и сам UUID более стандартная вещь, чем такой самопальный хеш.

Если вы таки хотите хеш по всему файлу, то учитывайте, что время его подсчёта будет как минимум равно времени чтения файла.  Поэтому замерьте cat file > /dev/null для начала.  Это и будет минимально достижимое время *в принципе*.


"Создание хешей файлов"
Отправлено weldpua2008 , 05-Янв-08 01:40 
>[оверквотинг удален]
>
>Буквами X обозначены те блоки, которые включены в хеш.  Тогда те
>блоки, которые обозначены буквой A можно произвольно менять, и хеш не
>изменится.
>
>Так что этот метод не подходит не только для криптогафических применений, но
>и для отслеживания изменений файлов.  Для глобальной идентификации файлов по
>всему миру он тоже не подходит.  Тут лучше посмотрите в
>строну хешей в сети edonkey.  Большой плюс -- они уже
>посчитаны для миллионов файлов и подходят не только для "идентификации"... =)

Во первых - Я максимум буду иметь 1-100млн файлов для которых хеш должен различатся.
Во вторых Я хочу читать из файлов в 5-25-ти(n) местах одинаковое количество Кб. Допустим из файла размером 100Мб Я прочитаю 25*128Кб непрерывным потоком и отправлю на mdsum - который и посчитает хеш... Алгоритм такой - берём размер файла, делим на сколько блоков читать(n), читаем n блоков а размер блока(r) будет опредёлён так - если размер файла/n >1M читаем r=1М, всё остальное - r =размер файла/(2*n), если размер файла <N байт - читаем весь файл...

>А вот если вы просто хотите создать некоторую маленькую строку, которой потом
>будете идентифицировать файл локально -- например, при добавлении файла в фильмотеку
>для него создаётся такой хеш, который служет идентификатором каким-то -- ваша
>схема вполне подходит.  Только тут лучше не изобретать велосипед, и
>использовать UUID, потому что для работы с ним уже много готовых
>библиотек есть.  Да и сам UUID более стандартная вещь, чем
>такой самопальный хеш.

Да - локальное применение
Не понял из манов по UUID -может ли она на основании фала выдавать данные...

>Если вы таки хотите хеш по всему файлу, то учитывайте, что время его подсчёта будет как минимум равно времени чтения файла.  Поэтому замерьте cat file > /dev/null для начала.  Это и будет минимально достижимое время *в принципе*.

нет. Про cat - понял, тут наверное и запираются md5sum &etc


"Создание хешей файлов"
Отправлено anonymous , 05-Янв-08 20:43 
>Во первых - Я максимум буду иметь 1-100млн файлов для которых хеш
>должен различатся.

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

>Да - локальное применение
>Не понял из манов по UUID -может ли она на основании фала
>выдавать данные...

Да, генерируется просто случайная, уникальная последовательность.  А зачем вам на основе данных файла?  У вас ведь задача не создать хеш, отражающий содержимое *всего* файла (иначе бы вы не задали вопрос), а просто создать некоторую уникальную последовательность символов, которую вы будете ассоциировать со своим файлом.  Именно для этого и придуман UUID.  Приведите, пожалуйста, конкретные примеры применения того хеша, который вы хотите сделать.

>>Если вы таки хотите хеш по всему файлу, то учитывайте, что время его подсчёта будет как минимум равно времени чтения файла.  Поэтому замерьте cat file > /dev/null для начала.  Это и будет минимально достижимое время *в принципе*.
>
>нет. Про cat - понял, тут наверное и запираются md5sum &etc

А давайте не гадать на кофейной гуще, а оперировать цифрами:

/usr/bin/time -v cat file > /dev/null
/usr/bin/time -v md5sum file


"Создание хешей файлов"
Отправлено weldpua2008 , 05-Янв-08 22:39 
>>Во первых - Я максимум буду иметь 1-100млн файлов для которых хеш
>>должен различатся.
>
>С вашей схемой можно элементарно создать два файла, для которых хеш будет
>одинаковый, миллионов файлов для этого не нужно.

Отвечаю ниже

>>Да - локальное применение
>>Не понял из манов по UUID -может ли она на основании фала
>>выдавать данные...
>
>Да, генерируется просто случайная, уникальная последовательность.  А зачем вам на основе
>данных файла?  У вас ведь задача не создать хеш, отражающий
>содержимое *всего* файла (иначе бы вы не задали вопрос), а просто
>создать некоторую уникальную последовательность символов, которую вы будете ассоциировать со своим
>файлом.  Именно для этого и придуман UUID.  Приведите, пожалуйста,
>конкретные примеры применения того хеша, который вы хотите сделать.

Мне нужен хеш, который Я буду получать на основании файла и что бы он был всегда одинаковый даже если переименовать файл!!!

Я уже писал, что Мне бы подошло использование - md5sum, но хеш строится как Я понимаю _для_всего_файла_ а значит что это очень долго. Я писал что замерял для 4Гб файла это порядка 2минут, Я же хочу не больше 5-ти секунд.

Во первых контент у Меня - музыка, фильмы, архивы, образы.

Как определить что файл уникален?

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

Во вторых какая вероятность что взятые 25 частей файла по  n байт будут похожи и при этом размер у них будет одинаковый?


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

>>>Если вы таки хотите хеш по всему файлу, то учитывайте, что время его подсчёта будет как минимум равно времени чтения файла.  Поэтому замерьте cat file > /dev/null для начала.  Это и будет минимально достижимое время *в принципе*.
>>
>>нет. Про cat - понял, тут наверное и запираются md5sum &etc
>
>А давайте не гадать на кофейной гуще, а оперировать цифрами:
>
>/usr/bin/time -v cat file > /dev/null
>/usr/bin/time -v md5sum file

В том то и дело что не хочу по всему файлу


"Создание хешей файлов"
Отправлено anonymous , 06-Янв-08 01:31 
>Во вторых какая вероятность что взятые 25 частей файла по  n
>байт будут похожи и при этом размер у них будет одинаковый?

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

>Для ускорения обсчета этого хеша Я хочу написать утилку наподобии cat, которая
>будет читать несколько частей файла и выводить их непрерывным потоком а
>в конце или в начале в вывод добавлять размер файла.

Вполне.  Можете обсчитать первый и последний мегабайт.  Приблизительно так:


#!/usr/bin/perl

use warnings;
use strict;

use Fcntl qw(SEEK_END);
use Digest::MD5;

our $file = $ARGV[0];

if(! -f $file)
{
  die("not a regular file");
}

my $size = (stat($file))[7];

my $ctx = Digest::MD5->new();

my $buf = '';
open(FILE, '<', $file) or die("can't open file");
read(FILE, $buf, 1024*1024);
$ctx->add($buf);

if($size >= 1024*1024*2)
{
  seek(FILE, 1024*1024, SEEK_END);
  read(FILE, $buf, 1024*1024);
  $ctx->add($buf);
}
close(FILE);

print($ctx->hexdigest, "\n");


"Создание хешей файлов"
Отправлено weldpua2008 , 06-Янв-08 12:15 
Спасибо
Поможете с файлами <2Mb

dom /my/ISO# time  ./cat  debian-40r1-i386-DVD-1.iso
c7d4f349f17fd5fd3c9d9857258e6ecf

real    0m0.056s
user    0m0.037s
sys     0m0.015s
dom /my/ISO# time  md5sum  debian-40r1-i386-DVD-1.iso
119abda7c941135d5bf382c386bca2ca  debian-40r1-i386-DVD-1.iso

real    4m26.976s
user    0m22.703s
sys     0m8.507s


"Создание хешей файлов"
Отправлено anonymous , 06-Янв-08 19:41 
>Спасибо
>Поможете с файлами <2Mb

В том скрипте ситуация файл <2Mb тоже обрабатывается.  В этом случае обсчитывается только первый мегабайт.


"Создание хешей файлов"
Отправлено weldpua2008 , 06-Янв-08 23:42 
>>Спасибо
>>Поможете с файлами <2Mb
>
>В том скрипте ситуация файл <2Mb тоже обрабатывается.  В этом случае
>обсчитывается только первый мегабайт.

Может кто поможет на php этот скрипт перевести?
Я для Перла и ПХП разные данные получаю и Мне кажется ПХП неправильно отрабатывает.

#!/usr/bin/php
<?php
$file="Fedora-8-i386-DVD.iso";
if(is_file($file))
{
    $handle=fopen($file,"r");
    $sizebyte=sprintf("%u", filesize($file));

    if($sizebyte<1024*1024*2)
     {
         $md=md5(fread($handle,filesize($file)));
     }

    if($sizebyte>=1024*1024*2)
    {
        $md=md5(fread($handle,1024*1024)+fseek($handle,1024*1024,SEEK_END));
    }
echo "\n".$md."\n";

}
?>


"Создание хешей файлов"
Отправлено weldpua2008 , 07-Янв-08 00:24 

>Может кто поможет на php этот скрипт перевести?
>Я для Перла и ПХП разные данные получаю и Мне кажется ПХП
>неправильно отрабатывает.
>

Вот поправил вроде:
#!/usr/bin/php
<?php
$file="Fedora-8-i386-DVD.iso";
if(is_file($file))
{
    $handle=fopen($file,"r");
    $sizebyte=sprintf("%u", filesize($file));

    if($sizebyte<1024*1024*2)
         $md=md5(fread($handle,filesize($file)));

    if($sizebyte>=1024*1024*2)
    {
        $m=fread($handle,1024*1024);
        fseek($handle,-1024*1024,SEEK_END);
        $m .=fread($handle,1024*1024);
        $md=md5($m);
    }

    echo "\n".$md."\n";
    fclose($handle);
}
?>


"Создание хешей файлов"
Отправлено anonymous , 07-Янв-08 02:01 
Вот только ещё бы if(){} else {} использовать, и имена понятные переменным дать.  Дался вам этот PHP...  Нормальным языкам такие хаки не нужны:
$sizebyte=sprintf("%u", filesize($file));

$m -> $data
$md -> $hash


"Создание хешей файлов"
Отправлено weldpua2008 , 07-Янв-08 02:42 
>Вот только ещё бы if(){} else {} использовать, и имена понятные переменным
>дать.  Дался вам этот PHP...  Нормальным языкам такие хаки
>не нужны:
>$sizebyte=sprintf("%u", filesize($file));
>$m -> $data
>$md -> $hash

+1 - Я пока нашел и вообще это хорошо что нашел :)
Но проблема в том что:
а - для перла Я еще не созрел
б - проект который Я делаю на ПХП и Мне хочется как можно меньше костылей со стороны. Тоесть Я не хотел бы использовать для написания и С/С++ и перл и пхп и сторонии утилиты вызывать вызовами :)
в - Я пока не добился того что бы тот хеш который Я получаю на ПХП соответствовал тому что выдает Перл, а значит Я не могу использовать и Перл и ПХП  -только что-то одно.


Еще Мне нужен алгорит обхода всех директорий, поторые лежат в даной директории.
Заранее благодарен.

#!/usr/bin/php
<?php
$file="Fedora-8-i386-DVD.iso";
if(is_file($file))
{
    $handle=fopen($file,"r");
    $sizebyte=sprintf("%u", filesize($file));

    if($sizebyte<1024*1024*2)
      {
         $mdhash=md5(fread($handle,filesize($file)));
      }
    else
      {
        $hash=fread($handle,1024*1024);
        fseek($handle,-1024*1024,SEEK_END);
        $hash .=fread($handle,1024*1024);
        $mdhash=md5($hash);
      }
    fclose($handle);
    echo "\n hash is == ".$mdhash."\n";
}
else
{
  echo "-not-is-file-";
}
?>


"Создание хешей файлов"
Отправлено anonymous , 07-Янв-08 20:42 
> в - Я пока не добился того что бы тот хеш
>который Я получаю на ПХП соответствовал тому что выдает Перл, а
>значит Я не могу использовать и Перл и ПХП  -только
>что-то одно.

Только что проверил -- тот скрипт на PHP, что в вашем сообщении и мой скрипт на Perl выдают одинаковые результаты.  По крайней мере, на файле размером 1.6Gb, больше я у себя не нашёл.

> Еще Мне нужен алгорит обхода всех директорий, поторые лежат в даной
>директории.

Ничего сложного.  (В Perl для этого вообще есть специальный пакет)  Проще всего написать рекурсивную функцию, которая делает следующее:

opendir()
readdir() и для каждого файла:
если файл -- выполняет ваш код
если каталог -- шаг рекусрии


Почитайте http://php.net/readdir там наверное даже готовый код есть


"Создание хешей файлов"
Отправлено eee , 07-Янв-08 22:35 
> Еще Мне нужен алгорит обхода всех директорий, поторые лежат в даной
>директории.
>Заранее благодарен.

http://pear.php.net/package/HTML_TreeMenu
То что нужно, файл map_fs.php


"Создание хешей файлов"
Отправлено phpcoder , 07-Янв-08 19:31 
Можно попробовать поиграться с head/tail, которым можно указать количество байт для чтения.



"Создание хешей файлов"
Отправлено Michael Quad , 21-Июл-08 22:40 
>[оверквотинг удален]
>но проблема в том что файл на 4Гб у меня для md5sum
>отдает хеш за ~3m, sha1sum за ~5m
>А Мне нужно очень быстро. Планируется получать хеши для видео файлов, образов
>дисков и т.д. Размер от 1Мб до 16Гб. Использование md5sum и
>т.д. - очень долго, мне бы что-то что читало бы несколько
>мелких частей (от 128Кб до 1Мб каждая например) файла из начала
>середины конца и конца например что то типа:
>./supercat file.avi| md5sum
>
>Помогите ПЛЗ

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