简体   繁体   中英

Calculate MD5 hash of a large file using javascript

How do you upload a 500mb file and get a MD5 hash with CryptoJS?

Here is my code:

$('#upload-file').change(function(){
    var reader = new FileReader();
    reader.addEventListener('load',function () {
        var hash = CryptoJS.MD5(CryptoJS.enc.Latin1.parse(this.result));
        window.md5 = hash.toString(CryptoJS.enc.Hex);
    });

    reader.readAsBinaryString(this.files[0]);
});

If the file is under 200mb, it works. Anything bigger, this.result is an empty "".

I've tried:

filereader api on big files

javascript FileReader - parsing long file in chunks

and almost got this to work , but console is complaining about .join("")

http://dojo4.com/blog/processing-huge-files-with-an-html5-file-input

CryptoJS has a progressive api for hash digests . The rest is taken form alediaferia's answer with slight modifications.

 function process() { getMD5( document.getElementById("my-file-input").files[0], prog => console.log("Progress: " + prog) ).then( res => console.log(res), err => console.error(err) ); } function readChunked(file, chunkCallback, endCallback) { var fileSize = file.size; var chunkSize = 4 * 1024 * 1024; // 4MB var offset = 0; var reader = new FileReader(); reader.onload = function() { if (reader.error) { endCallback(reader.error || {}); return; } offset += reader.result.length; // callback for handling read chunk // TODO: handle errors chunkCallback(reader.result, offset, fileSize); if (offset >= fileSize) { endCallback(null); return; } readNext(); }; reader.onerror = function(err) { endCallback(err || {}); }; function readNext() { var fileSlice = file.slice(offset, offset + chunkSize); reader.readAsBinaryString(fileSlice); } readNext(); } function getMD5(blob, cbProgress) { return new Promise((resolve, reject) => { var md5 = CryptoJS.algo.MD5.create(); readChunked(blob, (chunk, offs, total) => { md5.update(CryptoJS.enc.Latin1.parse(chunk)); if (cbProgress) { cbProgress(offs / total); } }, err => { if (err) { reject(err); } else { // TODO: Handle errors var hash = md5.finalize(); var hashHex = hash.toString(CryptoJS.enc.Hex); resolve(hashHex); } }); }); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/md5.js"></script> <input id="my-file-input" type="file"> <button onclick="process()">Process</button>

You don't need to read the whole file at once and feed it all in one go to CryptoJS routines.

You can create the hasher object, and feed chunks as you read them, and then get the final result.

Sample taken from the CryptoJS documentation

var sha256 = CryptoJS.algo.SHA256.create();
sha256.update("Message Part 1");
sha256.update("Message Part 2");
sha256.update("Message Part 3");
var hash = sha256.finalize();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM