Возобновление контекста хеширования файла без сохранения состояния

Короче вопрос

Как можно "возобновить hash_context" в PHP?


Фон и текущая ситуация

Цель программного обеспечения - получить большой кусок файла по частям (синхронно), рассчитать как MD5, так и SHA1 этого файла и сгенерировать ссылку для загрузки (полного файла). Что-то вроде Rapidshare, но вместо того, чтобы отправлять файл полностью, отправка фрагмента файла по фрагменту.

В настоящее время программное обеспечение работает с этой логикой:
Он получает куски файлов (10 МБ кусков большого файла) синхронно за файловую сессию. После получения всех фрагментов мне нужно вычислить MD5 и SHA1 для файла, который занимает очень много времени для файлов размером более 1 ГБ.

Псевдокод для финализатора файла (когда все чанки получены):

$fileKey = $_GET['KEY'];
$ctxMd5 = hash_init('md5');
$ctxSha1 = hash_init('sha1');

$fh = fopen('file/containing/all_chunks.tmp', 'r');
while(!feof($fh)) {
$data = fread($fh, CHUNK_SIZE);
    hash_update($ctxMd5, $data);
    hash_update($ctxSha1, $data);
}
$md5 = hash_final($ctxMd5);
$sha1= hash_final($ctxSha1);

saveFileHashes($fileKey, $md5, $sha1);

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


Решение проблемы

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

Псевдокод для чанкового получателя:

$chunkData = getIncommingChunkData();
$fileKey = $_GET['KEY'];

$ctxMd5 = resumeMd5HasingContext($fileKey);
$ctxSha1 = resumeSha1HasingContext($fileKey);

hash_update($ctxMd5, $chunkData);
hash_update($ctxSha1, $chunkData);

saveMd5HashingContext($fileKey, $ctxMd5)
saveSha1HashingContext($fileKey, $ctxSha1)

appendFileChunk($fileKey, $chunkData);

Эта проблема

Основная проблема заключается в том, что ресурсы PHP не сериализуемы, а также hash_init не обеспечивает способ возобновления контекста.

Хотелось бы узнать, как добиться всего изложенного выше?

1 ответ

Просто идея решить проблему: возможно, вам следует отделить процесс приема от процесса конкатенации / хеширования.

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

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

Другие вопросы по тегам