UNPKG

wsemi

Version:

A support package for web developer.

162 lines (147 loc) 5.9 kB
import { // createAdler32(): Promise<IHasher> // createBLAKE2b(bits?: number, key?: IDataType): Promise<IHasher> // default is 512 bits // createBLAKE2s(bits?: number, key?: IDataType): Promise<IHasher> // default is 256 bits // createBLAKE3(bits?: number, key?: IDataType): Promise<IHasher> // default is 256 bits // createCRC32(polynomial?: number): Promise<IHasher> // default polynomial is 0xedb88320, for CRC32C use 0x82f63b78 // createCRC64(polynomial?: number): Promise<IHasher> // default polynomial is 'c96c5795d7870f42' (ECMA) // createKeccak(bits?: 224 | 256 | 384 | 512): Promise<IHasher> // default is 512 bits // createMD4(): Promise<IHasher> createMD5, //createMD5(): Promise<IHasher> // createRIPEMD160(): Promise<IHasher> createSHA1, //createSHA1(): Promise<IHasher> // createSHA224(): Promise<IHasher> createSHA256, //createSHA256(): Promise<IHasher> createSHA384, //// createSHA384(): Promise<IHasher> createSHA512 //createSHA512(): Promise<IHasher> // createSHA3(bits?: 224 | 256 | 384 | 512): Promise<IHasher> // default is 512 bits // createSM3(): Promise<IHasher> // createWhirlpool(): Promise<IHasher> // createXXHash32(seed: number): Promise<IHasher> // createXXHash64(seedLow: number, seedHigh: number): Promise<IHasher> // createXXHash3(seedLow: number, seedHigh: number): Promise<IHasher> // createXXHash128(seedLow: number, seedHigh: number): Promise<IHasher> // createHMAC(hashFunction: Promise<IHasher>, key: IDataType): Promise<IHasher> } from 'hash-wasm' import get from 'lodash-es/get.js' import isestr from './isestr.mjs' import isnum from './isnum.mjs' import isblob from './isblob.mjs' import isfile from './isfile.mjs' import haskey from './haskey.mjs' import cdbl from './cdbl.mjs' /** * 計算檔案HASH值 * * 瀏覽器端輸入檔案Blob或File,可支援大檔 * * 因Node.js亦已支援Blob,可用new Blob([fs.readFileSync(fp)])取得Blob做為輸入 * * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/getFileHash.test.mjs Github} * @memberOf wsemi * @param {Blob|File} inp 輸入檔案Blob或File * @param {Object} [opt={}] 輸入設定物件,預設{} * @param {String} [opt.type='sha512'] 輸入計算HASH方法,預設'sha512' * @returns {Promise} 回傳Promise,此時若成功則resolve代表檔案HASH值,若失敗則reject錯誤訊息 * @example * * let test = async () => { * * let ms = [] * * let fdt = './_test_getFileBasicHash' * fsCreateFolder(fdt) //創建臨時任務資料夾 * * let fn = 't1.txt' * let fp = `${fdt}/abc/${fn}` * * fsWriteText(fp, 'xyz') * * let ab = fs.readFileSync(fp) * let bb = new Blob([ab]) * * let h1 = await getFileBasicHash(bb) * console.log('getFileBasicHash(sha512)', h1) * ms.push({ 'getFileBasicHash(sha512)': h1 }) * * let h2 = await getFileBasicHash(bb, { type: 'sha256' }) * console.log('getFileBasicHash(sha256)', h2) * ms.push({ 'getFileBasicHash(sha256)': h2 }) * * fsDeleteFolder(fdt) //刪除臨時任務資料夾 * * console.log('ms', ms) * return ms * } * await test() * .catch((err) => { * console.log(err) * }) * // getFileBasicHash(sha512) 4a3ed8147e37876adc8f76328e5abcc1b470e6acfc18efea0135f983604953a58e183c1a6086e91ba3e821d926f5fdeb37761c7ca0328a963f5e92870675b728 * // getFileBasicHash(sha256) 3608bca1e44ea6c4d268eb6db02260269892c0b42b86bbf1e77a6fa16c3c9282 * // ms [ * // { * // 'getFileBasicHash(sha512)': '4a3ed8147e37876adc8f76328e5abcc1b470e6acfc18efea0135f983604953a58e183c1a6086e91ba3e821d926f5fdeb37761c7ca0328a963f5e92870675b728' * // }, * // { * // 'getFileBasicHash(sha256)': '3608bca1e44ea6c4d268eb6db02260269892c0b42b86bbf1e77a6fa16c3c9282' * // } * // ] * */ async function getFileBasicHash(inp, opt = {}) { //瀏覽器crypto.subtle.digest是只支援一次性記憶體計算, 又只能非同步async計算, 故採用hash-wasm計算可支援超大檔 //check if (!isblob(inp) && !isfile(inp)) { console.log('inp', inp) return Promise.reject(`inp is not a Blob or File`) } //type let type = get(opt, 'type', '') if (!isestr(type)) { type = 'sha512' } //chunkSize let chunkSize = get(opt, 'chunkSize') if (!isnum(chunkSize)) { chunkSize = 64 * 1024 * 1024 //64mb } chunkSize = cdbl(chunkSize) //kp let kp = { 'MD5': createMD5, 'SHA-1': createSHA1, 'SHA-256': createSHA256, 'SHA-384': createSHA384, 'SHA-512': createSHA512, 'md5': createMD5, 'sha1': createSHA1, 'sha256': createSHA256, 'sha384': createSHA384, 'sha512': createSHA512, } // createMD5, //createMD5(): Promise<IHasher> // createSHA1, //createSHA1(): Promise<IHasher> // createSHA256, //createSHA256(): Promise<IHasher> // createSHA512, //createSHA512(): Promise<IHasher> // createSHA3 //createSHA3(bits?: 224 | 256 | 384 | 512): Promise<IHasher> // default is 512 bits //check if (!haskey(kp, type)) { return Promise.reject(`type[${type}] must be one of [ 'md5', 'sha1', 'sha256', 'sha384', 'sha512' ]`) } //funCreate let funCreate = get(kp, type) //hasher let hasher = await funCreate() //calc hash let offset = 0 while (offset < inp.size) { let chunk = inp.slice(offset, offset + chunkSize) let buffer = await chunk.arrayBuffer() hasher.update(new Uint8Array(buffer)) offset += chunkSize } let hashHex = hasher.digest() return hashHex } export default getFileBasicHash