繁体   English   中英

CryptoJS SHA256 大文件渐进式校验和

[英]CryptoJS SHA256 Large File Progressive Checksum

我正在尝试使用 CryptoJS 来获取大文件(大于 500MB)的校验和,因此浏览器不会崩溃。 我已经在使用带有分块功能的 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);
   };

我已经稍微清理了上面的代码; 有人可能会发现它很有用(这是经过测试并正常工作的):

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);
    });
  }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM