Создание хешей файлов для файлопомойки

Когда-то давно ( 2008 год) нужно было создание хешей файлов, причём не на основании md5sum() утилиты.
проблема в том что файл на 4Гб у меня для md5sum отдает хеш за ~3m, sha1sum за ~5m. А нужно очень быстро :)

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
 
#!/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");

Вот моя старая реализация на php5:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/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-";
}

Проскочил умный комментарий:

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


Leave a Comment

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Загрузка...
Menu Title