/** 公共方法类 */ import CryptoJs from 'crypto-js' import encHex from 'crypto-js/enc-hex' export function hashBlob(blob) { /** * 使用指定的算法计算hash值 */ function hashFileInternal(blob, alog) { let promise = Promise.resolve() promise = promise.then(() => hashBlob(blob)) /** * 更新文件块的hash值 */ function hashBlob(blob) { return new Promise((resolve, reject) => { const reader = new FileReader() reader.onload = ({ target }) => { const wordArray = CryptoJs.lib.WordArray.create(target.result) // 增量更新计算结果 alog.update(wordArray) resolve() } reader.readAsArrayBuffer(blob) }) } // 使用promise返回最终的计算结果 return promise.then(() => encHex.stringify(alog.finalize())) } // 同时计算文件的sha256和md5,并使用promise返回 return Promise.all([hashFileInternal(blob, CryptoJs.algo.SHA256.create()), hashFileInternal(blob, CryptoJs.algo.MD5.create())]) .then(([sha256sum, md5sum]) => ({ sha256sum, md5sum })) } export function hashFile(file) { /** * 使用指定的算法计算hash值 */ function hashFileInternal(file, alog) { // 指定块的大小,这里设置为20MB,可以根据实际情况进行配置 const chunkSize = 20 * 1024 * 1024 let promise = Promise.resolve() // 使用promise来串联hash计算的顺序。因为FileReader是在事件中处理文件内容的,必须要通过某种机制来保证update的顺序是文件正确的顺序 for (let index = 0; index < file.size; index += chunkSize) { promise = promise.then(() => hashBlob(file.slice(index, index + chunkSize))) } /** * 更新文件块的hash值 */ function hashBlob(blob) { return new Promise((resolve, reject) => { const reader = new FileReader() reader.onload = ({ target }) => { const wordArray = CryptoJs.lib.WordArray.create(target.result) // 增量更新计算结果 alog.update(wordArray) resolve() } reader.readAsArrayBuffer(blob) }) } // 使用promise返回最终的计算结果 return promise.then(() => encHex.stringify(alog.finalize())) } // 同时计算文件的sha256和md5,并使用promise返回 return Promise.all([hashFileInternal(file, CryptoJs.algo.SHA256.create()), hashFileInternal(file, CryptoJs.algo.MD5.create())]) .then(([sha256sum, md5sum]) => ({ sha256sum, md5sum })) }