Last active
June 3, 2016 20:30
-
-
Save DvdKhl/8559321 to your computer and use it in GitHub Desktop.
JavaScript File Hasher ( asm.js )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Copyright (c) 2013, DvdKhl | |
//All rights reserved. | |
// | |
//Redistribution and use in source and binary forms, with or without modification, | |
//are permitted provided that the following conditions are met: | |
// | |
// Redistributions of source code must retain the above copyright notice, this | |
// list of conditions and the following disclaimer. | |
// | |
// Redistributions in binary form must reproduce the above copyright notice, this | |
// list of conditions and the following disclaimer in the documentation and/or | |
// other materials provided with the distribution. | |
// | |
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
//DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | |
//ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
function ed2kasm(stdlib, foreign, heap) { | |
"use asm"; | |
var A0 = 0x67452301; | |
var B0 = 0xEFCDAB89; | |
var C0 = 0x98BADCFE; | |
var D0 = 0x10325476; | |
var processedBytes = 0; | |
var heapOffset = 0; | |
var data = new Uint32Array(heap); | |
var dataUInt8 = new Uint8Array(heap); | |
var state = new Uint32Array(heap, heapOffset += 9500 * 1024, 4); | |
var blockState = new Uint32Array(heap, heapOffset += 16, 4); | |
var tailInt8 = new Uint8Array(heap, heapOffset += 16, 128); | |
var tailInt32 = new Uint32Array(heap, heapOffset, 32); | |
var blockHashCount = 0; | |
var blockHashBufferLength = 0; | |
var blockHashBufferUInt32 = new Uint32Array(heap, heapOffset += 128, 16); | |
var blockHashBufferUInt8 = new Uint8Array(heap, heapOffset, 64); | |
function initialize() { | |
state[0] = A0; | |
state[1] = B0; | |
state[2] = C0; | |
state[3] = D0; | |
processedBytes = 0; | |
blockHashBufferLength = 0; | |
blockHashCount = 0; | |
for(var i = 0; i < 32; i++) tailInt32[i] = 0; | |
} | |
function hashCore(length) { | |
var offset = 0; | |
processedBytes += length; | |
blockState[0] = A0; | |
blockState[1] = B0; | |
blockState[2] = C0; | |
blockState[3] = D0; | |
var remainingLength = length; | |
while(remainingLength >= 64) { | |
transformMd4Block(blockState, data, offset); | |
remainingLength -= 64; | |
offset += 16; | |
} | |
if(remainingLength != 0) { | |
for(var i = 0; i < remainingLength; i++) { | |
tailInt8[i] = dataUInt8[length - remainingLength + i]; | |
} | |
for(var i = remainingLength; i < 128; i++) { | |
tailInt8[i] = 0; | |
} | |
} | |
var padding = remainingLength < 56 ? 56 : 120; | |
var bits = length << 3; | |
tailInt8[remainingLength] = 0x80; | |
tailInt8[padding + 0] = (bits ) & 0xFF; | |
tailInt8[padding + 1] = (bits >> 8) & 0xFF; | |
tailInt8[padding + 2] = (bits >> 16) & 0xFF; | |
tailInt8[padding + 3] = (bits >> 24) & 0xFF; | |
tailInt8[padding + 4] = ((bits >> 31) >> 1) & 0xFF; | |
tailInt8[padding + 5] = ((bits >> 31) >> 9) & 0xFF; | |
tailInt8[padding + 6] = ((bits >> 31) >> 17) & 0xFF; | |
tailInt8[padding + 7] = ((bits >> 31) >> 25) & 0xFF; | |
transformMd4Block(blockState, tailInt32, 0); | |
if(remainingLength >= 56) transformMd4Block(blockState, tailInt32, 16); | |
blockHashBufferUInt32.set(blockState, blockHashBufferLength); | |
blockHashBufferLength += 4; | |
blockHashCount++; | |
if(blockHashBufferLength == 16) { | |
transformMd4Block(state, blockHashBufferUInt32, 0); | |
blockHashBufferLength = 0; | |
console.log(state); | |
} | |
} | |
function transformMd4Block(state, data, offset) { | |
var aa = state[0], bb = state[1], cc = state[2], dd = state[3]; | |
aa += ((bb & cc) | ((~bb) & dd)) + data[offset + 0x0]; | |
aa = aa << 3 | aa >>> -3; | |
dd += ((aa & bb) | ((~aa) & cc)) + data[offset + 0x1]; | |
dd = dd << 7 | dd >>> -7; | |
cc += ((dd & aa) | ((~dd) & bb)) + data[offset + 0x2]; | |
cc = cc << 11 | cc >>> -11; | |
bb += ((cc & dd) | ((~cc) & aa)) + data[offset + 0x3]; | |
bb = bb << 19 | bb >>> -19; | |
aa += ((bb & cc) | ((~bb) & dd)) + data[offset + 0x4]; | |
aa = aa << 3 | aa >>> -3; | |
dd += ((aa & bb) | ((~aa) & cc)) + data[offset + 0x5]; | |
dd = dd << 7 | dd >>> -7; | |
cc += ((dd & aa) | ((~dd) & bb)) + data[offset + 0x6]; | |
cc = cc << 11 | cc >>> -11; | |
bb += ((cc & dd) | ((~cc) & aa)) + data[offset + 0x7]; | |
bb = bb << 19 | bb >>> -19; | |
aa += ((bb & cc) | ((~bb) & dd)) + data[offset + 0x8]; | |
aa = aa << 3 | aa >>> -3; | |
dd += ((aa & bb) | ((~aa) & cc)) + data[offset + 0x9]; | |
dd = dd << 7 | dd >>> -7; | |
cc += ((dd & aa) | ((~dd) & bb)) + data[offset + 0xA]; | |
cc = cc << 11 | cc >>> -11; | |
bb += ((cc & dd) | ((~cc) & aa)) + data[offset + 0xB]; | |
bb = bb << 19 | bb >>> -19; | |
aa += ((bb & cc) | ((~bb) & dd)) + data[offset + 0xC]; | |
aa = aa << 3 | aa >>> -3; | |
dd += ((aa & bb) | ((~aa) & cc)) + data[offset + 0xD]; | |
dd = dd << 7 | dd >>> -7; | |
cc += ((dd & aa) | ((~dd) & bb)) + data[offset + 0xE]; | |
cc = cc << 11 | cc >>> -11; | |
bb += ((cc & dd) | ((~cc) & aa)) + data[offset + 0xF]; | |
bb = bb << 19 | bb >>> -19; | |
aa += ((bb & (cc | dd)) | (cc & dd)) + data[offset + 0x0] + 0x5A827999; | |
aa = aa << 3 | aa >>> -3; | |
dd += ((aa & (bb | cc)) | (bb & cc)) + data[offset + 0x4] + 0x5A827999; | |
dd = dd << 5 | dd >>> -5; | |
cc += ((dd & (aa | bb)) | (aa & bb)) + data[offset + 0x8] + 0x5A827999; | |
cc = cc << 9 | cc >>> -9; | |
bb += ((cc & (dd | aa)) | (dd & aa)) + data[offset + 0xC] + 0x5A827999; | |
bb = bb << 13 | bb >>> -13; | |
aa += ((bb & (cc | dd)) | (cc & dd)) + data[offset + 0x1] + 0x5A827999; | |
aa = aa << 3 | aa >>> -3; | |
dd += ((aa & (bb | cc)) | (bb & cc)) + data[offset + 0x5] + 0x5A827999; | |
dd = dd << 5 | dd >>> -5; | |
cc += ((dd & (aa | bb)) | (aa & bb)) + data[offset + 0x9] + 0x5A827999; | |
cc = cc << 9 | cc >>> -9; | |
bb += ((cc & (dd | aa)) | (dd & aa)) + data[offset + 0xD] + 0x5A827999; | |
bb = bb << 13 | bb >>> -13; | |
aa += ((bb & (cc | dd)) | (cc & dd)) + data[offset + 0x2] + 0x5A827999; | |
aa = aa << 3 | aa >>> -3; | |
dd += ((aa & (bb | cc)) | (bb & cc)) + data[offset + 0x6] + 0x5A827999; | |
dd = dd << 5 | dd >>> -5; | |
cc += ((dd & (aa | bb)) | (aa & bb)) + data[offset + 0xA] + 0x5A827999; | |
cc = cc << 9 | cc >>> -9; | |
bb += ((cc & (dd | aa)) | (dd & aa)) + data[offset + 0xE] + 0x5A827999; | |
bb = bb << 13 | bb >>> -13; | |
aa += ((bb & (cc | dd)) | (cc & dd)) + data[offset + 0x3] + 0x5A827999; | |
aa = aa << 3 | aa >>> -3; | |
dd += ((aa & (bb | cc)) | (bb & cc)) + data[offset + 0x7] + 0x5A827999; | |
dd = dd << 5 | dd >>> -5; | |
cc += ((dd & (aa | bb)) | (aa & bb)) + data[offset + 0xB] + 0x5A827999; | |
cc = cc << 9 | cc >>> -9; | |
bb += ((cc & (dd | aa)) | (dd & aa)) + data[offset + 0xF] + 0x5A827999; | |
bb = bb << 13 | bb >>> -13; | |
aa += (bb ^ cc ^ dd) + data[offset + 0x0] + 0x6ED9EBA1; | |
aa = aa << 3 | aa >>> -3; | |
dd += (aa ^ bb ^ cc) + data[offset + 0x8] + 0x6ED9EBA1; | |
dd = dd << 9 | dd >>> -9; | |
cc += (dd ^ aa ^ bb) + data[offset + 0x4] + 0x6ED9EBA1; | |
cc = cc << 11 | cc >>> -11; | |
bb += (cc ^ dd ^ aa) + data[offset + 0xC] + 0x6ED9EBA1; | |
bb = bb << 15 | bb >>> -15; | |
aa += (bb ^ cc ^ dd) + data[offset + 0x2] + 0x6ED9EBA1; | |
aa = aa << 3 | aa >>> -3; | |
dd += (aa ^ bb ^ cc) + data[offset + 0xA] + 0x6ED9EBA1; | |
dd = dd << 9 | dd >>> -9; | |
cc += (dd ^ aa ^ bb) + data[offset + 0x6] + 0x6ED9EBA1; | |
cc = cc << 11 | cc >>> -11; | |
bb += (cc ^ dd ^ aa) + data[offset + 0xE] + 0x6ED9EBA1; | |
bb = bb << 15 | bb >>> -15; | |
aa += (bb ^ cc ^ dd) + data[offset + 0x1] + 0x6ED9EBA1; | |
aa = aa << 3 | aa >>> -3; | |
dd += (aa ^ bb ^ cc) + data[offset + 0x9] + 0x6ED9EBA1; | |
dd = dd << 9 | dd >>> -9; | |
cc += (dd ^ aa ^ bb) + data[offset + 0x5] + 0x6ED9EBA1; | |
cc = cc << 11 | cc >>> -11; | |
bb += (cc ^ dd ^ aa) + data[offset + 0xD] + 0x6ED9EBA1; | |
bb = bb << 15 | bb >>> -15; | |
aa += (bb ^ cc ^ dd) + data[offset + 0x3] + 0x6ED9EBA1; | |
aa = aa << 3 | aa >>> -3; | |
dd += (aa ^ bb ^ cc) + data[offset + 0xB] + 0x6ED9EBA1; | |
dd = dd << 9 | dd >>> -9; | |
cc += (dd ^ aa ^ bb) + data[offset + 0x7] + 0x6ED9EBA1; | |
cc = cc << 11 | cc >>> -11; | |
bb += (cc ^ dd ^ aa) + data[offset + 0xF] + 0x6ED9EBA1; | |
bb = bb << 15 | bb >>> -15; | |
state[0] += aa; | |
state[1] += bb; | |
state[2] += cc; | |
state[3] += dd; | |
} | |
function hashFinal() { | |
var bits = (blockHashCount * 16) << 3; | |
for(var i = blockHashBufferLength; i < 16; i+=4) { | |
blockHashBufferUInt32[i + 0] = 0; | |
blockHashBufferUInt32[i + 1] = 0; | |
blockHashBufferUInt32[i + 2] = 0; | |
blockHashBufferUInt32[i + 3] = 0; | |
} | |
blockHashBufferUInt8[blockHashBufferLength * 4] = 0x80; | |
blockHashBufferUInt8[56] = (bits ) & 0xFF; | |
blockHashBufferUInt8[57] = (bits >> 8) & 0xFF; | |
blockHashBufferUInt8[58] = (bits >> 16) & 0xFF; | |
blockHashBufferUInt8[59] = (bits >> 24) & 0xFF; | |
blockHashBufferUInt8[60] = ((bits >> 31) >> 1) & 0xFF; | |
blockHashBufferUInt8[61] = ((bits >> 31) >> 9) & 0xFF; | |
blockHashBufferUInt8[62] = ((bits >> 31) >> 17) & 0xFF; | |
blockHashBufferUInt8[63] = ((bits >> 31) >> 25) & 0xFF; | |
transformMd4Block(state, blockHashBufferUInt32, 0); | |
} | |
return { | |
initialize: initialize, | |
hashCore: hashCore, | |
hashFinal: hashFinal | |
}; | |
} | |
var CHUNKSIZE = 9500 * 1024; | |
function ed2k() { | |
var heap = new ArrayBuffer(CHUNKSIZE + 16 + 16 + 128 + 64); | |
this.asmBlock = new Uint8Array(heap); | |
this.asm = ed2kasm(null, {}, heap); | |
this.processedBytes = 0; | |
this.blueHash = new Uint8Array(16); | |
this.redHash = new Uint8Array(16); | |
this.blueIsRed = true; | |
} | |
ed2k.prototype.initialize = function() { | |
this.asm.initialize(); | |
this.processedBytes = 0; | |
this.blueIsRed = true; | |
}; | |
ed2k.prototype.transformBlock = function(data) { | |
var dv = new Uint8Array(data); | |
this.asmBlock.set(dv, 0); | |
this.asm.hashCore(data.byteLength); | |
this.processedBytes += data.byteLength; | |
}; | |
function copyHash(dst, src, offset) { | |
for(var i = 0; i < 16; i++) dst[i] = src[CHUNKSIZE + offset + i]; | |
} | |
ed2k.prototype.transformFinalBlock = function(data) { | |
if(data && data.byteLength != 0) throw "transformFinalBlock data.byteLength != 0 not supported"; | |
this.asm.hashFinal(); | |
if(this.processedBytes < CHUNKSIZE) { | |
copyHash(this.blueHash, this.asmBlock, 16); | |
} else if(this.processedBytes == CHUNKSIZE) { | |
copyHash(this.blueHash, this.asmBlock, 16); | |
this.asm.hashCore(0); | |
copyHash(this.redHash, this.asmBlock, 0); | |
this.blueIsRed = false; | |
} else { | |
copyHash(this.blueHash, this.asmBlock, 0); | |
if((this.processedBytes % CHUNKSIZE) == 0) { | |
this.asm.hashCore(0); | |
copyHash(this.redHash, this.asmBlock, 0); | |
this.blueIsRed = false; | |
} | |
} | |
} | |
ed2k.prototype.getHash = function() { return this.blueHash; } | |
ed2k.prototype.getAltHash = function() { return this.redHash ? this.redHash : this.blueHash; } | |
ed2k.prototype.hasAltHash = function() { return this.blueIsRed; } | |
ed2k.prototype.getChunkHash = function() { | |
copyHash(this.redHash, this.asmBlock, 16); | |
return this.redHash; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>JS Ed2k File Hasher</title> | |
</head> | |
<body> | |
<input type="file" id="files" name="file" /> | |
<div id="readBytesButtons"><button>Hash File</button></div> | |
<div>Read Speed: <span id="readspeed"/>mb/s</div> | |
<div>Hash Speed: <span id="hashspeed"/>mb/s</div> | |
<div>Final Hash: <span id="hash"/></div> | |
<div>Chunk Hashes:<br> <pre id="chunkhashes"/></div> | |
<script src="reader.js"></script> | |
<script> | |
document.querySelector('#readBytesButtons').addEventListener('click', function(evt) { | |
if (evt.target.tagName.toLowerCase() == 'button') { | |
processFile(document.getElementById('files').files[0], 0); | |
} | |
}, false); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Copyright (c) 2013, DvdKhl | |
//All rights reserved. | |
// | |
//Redistribution and use in source and binary forms, with or without modification, | |
//are permitted provided that the following conditions are met: | |
// | |
// Redistributions of source code must retain the above copyright notice, this | |
// list of conditions and the following disclaimer. | |
// | |
// Redistributions in binary form must reproduce the above copyright notice, this | |
// list of conditions and the following disclaimer in the documentation and/or | |
// other materials provided with the distribution. | |
// | |
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
//DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | |
//ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
var startedOn = 0; | |
var bytesRead = 0; | |
var pendingChunks = 0; | |
var bytesProcessed = 0; | |
var CHUNKSIZE = 9500 * 1024; | |
var callback; | |
var worker = new Worker("readerChunk.js"); | |
worker.addEventListener('message', function(e) { | |
var data = e.data; | |
switch (data.cmd) { | |
case 'finalHash': | |
document.getElementById('hash').textContent = data.hash; | |
break; | |
case 'chunkDone': | |
bytesProcessed += data.chunkSize; | |
var speed = (bytesProcessed / (window.performance.now() - startedOn)) / 1024; | |
document.getElementById('hashspeed').textContent = speed; | |
pendingChunks--; | |
if(callback && pendingChunks < 4) { | |
callback(); | |
callback = null; | |
} | |
}; | |
}, false); | |
function processFile(file, chunkIndex) { | |
if(chunkIndex == 0) { | |
worker.postMessage({'cmd': 'initialize'}); | |
bytesRead = 0; | |
pendingChunks = 0; | |
bytesProcessed = 0; | |
startedOn = window.performance.now(); | |
document.getElementById('chunkhashes').textContent = ""; | |
} | |
var first = chunkIndex * CHUNKSIZE; | |
var last = first + Math.min(file.size - first, CHUNKSIZE); | |
var isLastChunk = last == file.size; | |
var reader = new FileReader(); | |
reader.onloadend = function(evt) { | |
if (evt.target.readyState == FileReader.DONE) { // DONE == 2 | |
bytesRead += evt.target.result.byteLength; | |
var speed = (bytesRead / (window.performance.now() - startedOn)) / 1024; | |
document.getElementById('readspeed').textContent = speed; | |
if(!isLastChunk) { | |
if(pendingChunks > 8) { | |
callback = function() { processFile(file, chunkIndex + 1); }; | |
} else { | |
processFile(file, chunkIndex + 1); | |
} | |
} | |
pendingChunks++; | |
worker.postMessage({'cmd': 'hashChunk', 'chunk': evt.target.result, 'isLastChunk': isLastChunk}, [evt.target.result]); | |
} | |
} | |
var blob = file.slice(first, last); | |
reader.readAsArrayBuffer(blob); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Copyright (c) 2013, DvdKhl | |
//All rights reserved. | |
// | |
//Redistribution and use in source and binary forms, with or without modification, | |
//are permitted provided that the following conditions are met: | |
// | |
// Redistributions of source code must retain the above copyright notice, this | |
// list of conditions and the following disclaimer. | |
// | |
// Redistributions in binary form must reproduce the above copyright notice, this | |
// list of conditions and the following disclaimer in the documentation and/or | |
// other materials provided with the distribution. | |
// | |
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
//DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | |
//ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
importScripts('ed2k.js'); | |
var hasher = new ed2k(); | |
function processChunk(data, isLastChunk) { | |
//for(i=0; i<10000000; i++) var sf = {}; | |
hasher.transformBlock(data); | |
self.postMessage({'cmd': 'chunkDone', 'chunkSize': data.byteLength}); | |
if(isLastChunk) { | |
hasher.transformFinalBlock(); | |
var hex = ""; | |
var hash = hasher.getHash(); | |
for (var i = 0; i < hash.length; i++) hex += ("00" + hash[i].toString(16)).slice(-2); | |
self.postMessage({'cmd': 'finalHash', 'hash': hex}); | |
} | |
} | |
self.addEventListener('message', function(e) { | |
var data = e.data; | |
switch (data.cmd) { | |
case 'initialize': | |
hasher.initialize(); | |
break; | |
case 'hashChunk': | |
processChunk(data.chunk, data.isLastChunk); | |
break; | |
}; | |
}, false); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment