【问题标题】:CryptoJS SHA256 Large File Progressive ChecksumCryptoJS SHA256 大文件渐进校验和
【发布时间】:2020-07-10 05:35:37
【问题描述】:

我正在尝试使用 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);
   };

【问题讨论】:

  • 你能提供一个小提琴吗?
  • 我没有尝试过,但可能是因为fileSlicer = file.slice(start, stop + 1); 行中的+1。删除它。
  • @ArtjomB。你不讨厌有什么东西正盯着你看而你看不到吗?就是这样!谢谢!
  • 是的,我讨厌这个。我只注意到这一点,因为我为一个 SO 问题写了这样的东西。
  • 您的代码是否可以使用上面建议的删除“+ 1”的修复方法?您是否能够优化或减少代码并使其符合打字稿?

标签: javascript hash sha256 cryptojs chunking


【解决方案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);
    });
  }

}

【讨论】:

  • 由于块是异步读取的,你怎么知道哈希是以正确的顺序计算的?这篇文章基本上是这样做的,但是有代码来检查它是否以正确的顺序完成:medium.com/@0xVaccaro/…
  • 它总是在等待下一个切片,所以我认为它不会出现故障
猜你喜欢
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
相关资源
最近更新 更多