2016-08-23 37 views
1

500MBのファイルをアップロードして、CryptoJSでMD5ハッシュを取得するにはどうすればよいですか?ファイルが200メガバイトの下にあるJavaScriptを使用して大きなファイルのMD5ハッシュを計算する

$('#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]); 
}); 

場合、それは動作します:

は、ここに私のコードです。何よりも大きい、this.resultは空 ""です。

filereader api on big files

javascript FileReader - parsing long file in chunks

、ほとんどこれが動作するようになったが、コンソールは.join( "")

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

+0

、** MD5を使用しないでください。 ** MD5は壊れています**。 SHA-256以上を使用してください。 – jcaron

+0

このプロジェクトにはMD5を使用する必要があります。 –

答えて

5

CryptoJSから採取progressive api for hash digestsを有しています。残りの部分は少し修正して形alediaferia's answerとなります。これは、外部サービスによって要求されない限り

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>
余談として

+0

ホールド、それは間違ったハッシュをまだ与える –

+0

ありがとうTamas。私はsimple.txtファイルを試しました、それは動作します。しかし、同じファイルの.zipを試したところ、ハッシュは正しくありません。 –

+0

バイナリの迷惑メールには何かがあります。私はchromeがutf8として解読しようとしていると思います。 –

0

文句を言っている:

私が試してみましたファイル全体を一度に読み取って1つにまとめてCryptoJSルーチンに渡す必要はありません。

ハッシャーオブジェクトを作成し、読み込んだときにチャンクをフィードして、最終結果を得ることができます。

サンプル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(); 
関連する問題