如何生成校验和并在Javascript中转换为64位非常大的文件而不会溢出RAM?

前端之家收集整理的这篇文章主要介绍了如何生成校验和并在Javascript中转换为64位非常大的文件而不会溢出RAM?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
题:

>如何正确生成校验和,这是独一无二的,与浏览器无关的一致性?另外,我想将SHA256 / MD5校验和字符串转换为64位.
>如何在没有大量RAM要求的情况下正确读取文件生成校验和?即我们如何在不影响RAM的情况下处理1 GB文件

例如Is it possible to read a file without loading it into memory?(见答案)

This project似乎很有希望,但也无法让它发挥作用.

我的目的是在X MB的块中逐步/递增地生成校验和.这可能有助于避免一次使用太多RAM.
以下是代码,它没有按预期工作:

  1. let SIZE_CHECKSUM = 10 * Math.pow(1024,2); // 10 MB; But can be 1 MB too
  2. async function GetChecksum (file: File):
  3. Promise<string>
  4. {
  5. let hashAlgorithm: CryptoJS.lib.IHasher<Object> = CryptoJS.algo.SHA256.create();
  6. let totalChunks: number = Math.ceil(file.size / SIZE_CHECKSUM);
  7. for (let chunkCount = 0,start = 0,end = 0; chunkCount < totalChunks; ++chunkCount)
  8. {
  9. end = Math.min(start + SIZE_CHECKSUM,file.size);
  10. let resultChunk: string = await (new Response(file.slice(start,end)).text());
  11. hashAlgorithm.update(resultChunk);
  12. start = chunkCount * SIZE_CHECKSUM;
  13. }
  14. let long: bigInt.BigInteger = bigInt.fromArray(hashAlgorithm.finalize().words,16,false);
  15. if(long.compareTo(bigInt.zero) < 0)
  16. long = long.add(bigInt.one.shiftLeft(64));
  17. return long.toString();
  18. }

它在不同的浏览器中显示不同的结果

解决方法

下面的代码中存在一个逻辑问题:
  1. start = chunkCount * SIZE_CHECKSUM; // <--- bug

变量start初始化为0,然后在第一次迭代中再次重置为0,这是不对的.
以下是使用问题中提到的相同库获取32字节SHA5校验和的方法:“emn178 / js-sha256”.

该库不提供Typescript接口,但我们可以简单地定义如下:

  1. // Sha256.d.ts (also name the corresponding JS file as "Sha256.js")
  2. declare class Sha256 {
  3. update (data: ArrayBuffer): Sha256;
  4. hex (): string;
  5. }
  6.  
  7. declare var sha256: any;
  8. declare interface sha256 {
  9. create (): Sha256;
  10. }

然后使用如下:

  1. import "./external/Sha256"
  2.  
  3. async function GetChecksum (file: File):
  4. Promise<string>
  5. {
  6. let algorithm = sha256.create();
  7. for(let chunkCount = 0,totalChunks = Math.ceil(file.size / SIZE_CHECKSUM);
  8. chunkCount < totalChunks;
  9. ++chunkCount)
  10. {
  11. let start = chunkCount * SIZE_CHECKSUM,end = Math.min(start + SIZE_CHECKSUM,file.size);
  12. algorithm.update(await (new Response(file.slice(start,end)).arrayBuffer()));
  13. }
  14. return algorithm.hex();
  15. }

上面的代码在我的所有浏览器中为任何块大小生成相同的校验和.

猜你在找的JavaScript相关文章