JSFiddle - React, Tailwind, and code Playground

by artjomb

HTML

<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/md5.js"></script>
<form method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="videoupload" id="videoupload"/>
    <input type="checkbox" name="singleHash" id="singleHash"/><label for="singleHash">Run un-chunked version</label>
    <p>
        <label for="hashValue">Un-chunked:</label><input type="text" name="hashValue" id="hashValue"/>
    </p>
    <p>
        <label for="hashValueSplit">Chunked:</label><input type="text" name="hashValueSplit" id="hashValueSplit"/>
    </p>
    <p>progress: <span id="num">0/?</span> chunks <span id="time"></span></p>
</form>

CSS

/*
This script is for chunking a file and computing the hash in chunk through a web worker to reduce the problems of doing the hashing in the main thread.
*/
#singleHash:not(:checked) ~ p > #hashValue, #singleHash:not(:checked) ~  p > [for="hashValue"]{
    display: none;
}

JavaScript

// The web worker string invokation is copied from http://stackoverflow.com/a/10372280 by Rob W

function series(tasks, done){
    if(!tasks || tasks.length === 0) {
        done();
    } else {
        tasks[0](function(){
            series(tasks.slice(1), done);
        });
    }
}

function webWorkerOnMessage(e){
    function arrayBufferToWordArray(ab) {
        var i8a = new Uint8Array(ab);
        var a = [];
        for (var i = 0; i < i8a.length; i += 4) {
          a.push(i8a[i] << 24 | i8a[i + 1] << 16 | i8a[i + 2] << 8 | i8a[i + 3]);
        }
        return CryptoJS.lib.WordArray.create(a, i8a.length);
    }
    if (e.data.type === "create") {
        md5 = CryptoJS.algo.MD5.create();
        postMessage({type: "create"});
    } else if (e.data.type === "update") {
        md5.update(arrayBufferToWordArray(e.data.chunk));
        postMessage({type: "update"});
    } else if (e.data.type === "finish") {
        postMessage({type: "finish", hash: ""+md5.finalize()});
    }
}

// URL.createObjectURL
window.URL = window.URL || window.webkitURL;
        
// "Server response", used in all examples
var response = 
    "importScripts('https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/md5.js');"+
    //"importScripts('https://cdn.rawgit.com/satazor/SparkMD5/master/spark-md5.min.js');"+
    "var md5, cryptoType;"+
    "self.onmessage = "+webWorkerOnMessage.toString();

var blob;
try {
    blob = new Blob([response], {type: 'application/javascript'});
} catch (e) { // Backwards-compatibility
    window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
    blob = new BlobBuilder();
    blob.append(response);
    blob = blob.getBlob();
}
var worker = new Worker(URL.createObjectURL(blob));

// Reference: https://code.google.com/p/crypto-js/#MD5
function handleFileSelect(evt) 
{	
    var files = evt.target.files; // FileList object
    
    var chunksize = 1000000;
    var i = 0, 
        f = files[i],
       ...