问题 :
如何正确生成校验和,唯一且一致,独立于浏览器?另外,我想将SHA256 / MD5校验和字符串转换为64位。
如何在不占用大量RAM的情况下正确读取文件以生成校验和?即我们如何处理1 GB文件而又不影响RAM
这个项目看起来很有希望,但也无法成功。
我的意图是逐步/递增地在X MB的块中生成校验和。这可能有助于避免一次使用过多的RAM。 以下是代码,无法正常工作:
let SIZE_CHECKSUM = 10 * Math.pow(1024, 2); // 10 MB; But can be 1 MB too async function GetChecksum (file: File): Promise<string> { let hashAlgorithm: CryptoJS.lib.IHasher<Object> = CryptoJS.algo.SHA256.create(); let totalChunks: number = Math.ceil(file.size / SIZE_CHECKSUM); for (let chunkCount = 0, start = 0, end = 0; chunkCount < totalChunks; ++chunkCount) { end = Math.min(start + SIZE_CHECKSUM, file.size); let resultChunk: string = await (new Response(file.slice(start, end)).text()); hashAlgorithm.update(resultChunk); start = chunkCount * SIZE_CHECKSUM; } let long: bigInt.BigInteger = bigInt.fromArray(hashAlgorithm.finalize().words, 16, false); if(long.compareTo(bigInt.zero) < 0) long = long.add(bigInt.one.shiftLeft(64)); return long.toString(); }
在不同的浏览器中显示不同的结果。
在下面的代码行中有一个逻辑问题:
start = chunkCount * SIZE_CHECKSUM; // <--- bug
将该变量 start 初始化为0,然后在第一次迭代中再次重置为0,这是不对的。 以下是使用问题中提到的相同库“ emn178 / js-sha256 ” 获得32字节SHA5校验和的方法。
start
该库不提供Typescript接口,但是我们可以如下定义:
// Sha256.d.ts (also name the corresponding JS file as "Sha256.js") declare class Sha256 { update (data: ArrayBuffer): Sha256; hex (): string; } declare var sha256: any; declare interface sha256 { create (): Sha256; }
然后按以下方式使用它:
import "./external/Sha256" async function GetChecksum (file: File): Promise<string> { let algorithm = sha256.create(); for(let chunkCount = 0, totalChunks = Math.ceil(file.size / SIZE_CHECKSUM); chunkCount < totalChunks; ++chunkCount) { let start = chunkCount * SIZE_CHECKSUM, end = Math.min(start + SIZE_CHECKSUM, file.size); algorithm.update(await (new Response(file.slice(start, end)).arrayBuffer())); } return algorithm.hex(); }
上面的代码在我所有的浏览器中为任何块大小生成相同的校验和。