CryptoJS SHA256 Прогрессивная контрольная сумма больших файлов

Я пытаюсь использовать CryptoJS для получения контрольной суммы больших файлов (больше 500 МБ), чтобы браузер не зависал. Я уже использую Web Worker с фрагментацией. Итак, я пытаюсь постепенно использовать каждый фрагмент, когда я перебираю фрагменты, чтобы обновить CryptoJS, чтобы начать создание контрольной суммы. Тем не менее, он все еще возвращает неправильную контрольную сумму в конце, когда я завершаю. Кажется, что он возвращает только контрольную сумму последнего фрагмента, а не контрольную сумму всех фрагментов. Можете ли вы сообщить мне, что я делаю неправильно.

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

 var sha256 = CryptoJS.algo.SHA256.create(),
     sha256Update,
     checksum = [],
     chunker = function(workerData) {                            

       var file = workerData.fileBlob,
           totalFileSize = file.size,
           chunkLength = 3145728,
           start = 0,
           stop = chunkLength,
           i = 0, readSlicer,
           fileSlicer,
           chunk,
           chunkUint8,
           timerCounter = 0,
           hashConvert;

      var checker = function() {

          start = stop;
          stop += chunkLength;

          if(start >= totalFileSize) {
               console.log("Done reading file!", stop, totalFileSize);
               sha256Update.finalize();

               console.log("CheckSum : ", sha256Update._hash.toString(CryptoJS.enc.Hex));
               return;
                               }
               readBlock(start, chunkLength, file);
      };

      var readBlock = function(start, chunkLength, file) {

          readSlicer = new FileReaderSync();
          fileSlicer = file.slice(start, stop + 1);

          chunk = readSlicer.readAsArrayBuffer(fileSlicer);
          chunkUint8 = new Uint8Array(chunk);
          var wordArr = CryptoJS.lib.WordArray.create(chunkUint8);
              sha256Update = sha256.update(wordArr);
              checksum.push(sha256Update);
              checker();

      };

          readBlock(start, chunkLength, file);
   };

person Claude    schedule 19.04.2015    source источник
comment
Можете ли вы предоставить скрипку?   -  person Artjom B.    schedule 19.04.2015
comment
Я не пробовал, но, вероятно, это из-за +1 в строке fileSlicer = file.slice(start, stop + 1);. Убери это.   -  person Artjom B.    schedule 19.04.2015
comment
@ArtjomB. Разве ты не ненавидишь, когда что-то бросается тебе в глаза, а ты этого не видишь? Вот оно! Спасибо!   -  person Claude    schedule 19.04.2015
comment
Да, я ненавижу это. Я заметил это только потому, что написал что-то подобное для вопроса SO.   -  person Artjom B.    schedule 19.04.2015
comment
Ваш код работает с предложенным исправлением удаления + 1 выше? Удалось ли вам оптимизировать или сократить код, чтобы он соответствовал машинописному тексту?   -  person iammilind    schedule 24.08.2018


Ответы (1)


Я немного подчистил приведенный выше код; кто-то может найти это полезным (это проверено и работает правильно):

import CryptoJS from 'crypto-js';


class ChecksumService {

  async sha256(file: File): Promise<string> {
    let sha256 = CryptoJS.algo.SHA256.create();
    const sliceSize = 10_485_760; // 10 MiB
    let start = 0;

    while (start < file.size) {
      const slice: Uint8Array = await this.readSlice(file, start, sliceSize);
      const wordArray = CryptoJS.lib.WordArray.create(slice);
      sha256 = sha256.update(wordArray);
      start += sliceSize;
    }

    sha256.finalize();

    return sha256._hash.toString();
  }

  private async readSlice(file: File, start: number, size: number): Promise<Uint8Array> {
    return new Promise<Uint8Array>((resolve, reject) => {
      const fileReader = new FileReader();
      const slice = file.slice(start, start + size);

      fileReader.onload = () => resolve(new Uint8Array(fileReader.result as any));
      fileReader.onerror = reject;
      fileReader.readAsArrayBuffer(slice);
    });
  }

}
person Zoltan Tarcsay    schedule 09.07.2020
comment
Поскольку куски считываются асинхронно, как узнать, что хэш вычисляется в правильном порядке? Эта статья в основном делает то же самое, но содержит код для проверки правильности порядка: medium.com/@0xVaccaro/ - person Mischa; 14.07.2021
comment
он всегда ожидает следующего фрагмента, поэтому я не думаю, что он может выйти из строя - person Zoltan Tarcsay; 15.07.2021