Javascriptを使用してサーバーにアップロードする前に、ファイルのMD5ハッシュを計算する方法はありますか?
MD5アルゴリズムには JS実装 がありますが、古いブラウザは一般にローカルファイルシステムからファイルを読み取ることができません。
私は2009年にそれを書きました。では、新しいブラウザはどうですか?
FileAPI をサポートするブラウザを使用すると、ファイルの内容を読み取ることができます-ユーザーは選択する必要がありますそれ、<input>
要素またはドラッグアンドドロップ。 2013年1月現在、主要なブラウザは次のように積み重なっています。
大きなファイルを効率的にハッシュするために、インクリメンタルmd5を実装するライブラリを作成しました。基本的に、メモリを低く保つためにファイルをチャンクで読み取り、増分的にハッシュします。 readmeに基本的な使用法と例があります。
HTML5 FileAPIが必要なので、必ず確認してください。テストフォルダーには完全な例があります。
CryptoJSのMD5関数 および HTML5 FileReader API を使用してMD5ハッシュを計算するのは非常に簡単です。次のコードスニペットは、バイナリデータを読み取り、ブラウザにドラッグされた画像からMD5ハッシュを計算する方法を示しています。
var holder = document.getElementById('holder');
holder.ondragover = function() {
return false;
};
holder.ondragend = function() {
return false;
};
holder.ondrop = function(event) {
event.preventDefault();
var file = event.dataTransfer.files[0];
var reader = new FileReader();
reader.onload = function(event) {
var binary = event.target.result;
var md5 = CryptoJS.MD5(binary).toString();
console.log(md5);
};
reader.readAsBinaryString(file);
};
ドラッグアンドドロップ領域を表示するには、CSSを追加することをお勧めします。
#holder {
border: 10px dashed #ccc;
width: 300px;
height: 300px;
}
#holder.hover {
border: 10px dashed #333;
}
ドラッグアンドドロップ機能の詳細については、こちらをご覧ください。 File API&FileReader
Google Chromeバージョン32でサンプルをテストしました。
FileAPIを使用する必要があります。最新のFFとChromeで使用できますが、IE9では使用できません。上記のmd5 JS実装を入手してください。 JSが遅すぎる(大きな画像ファイルの場合は数分)ので、私はこれを試して放棄しました。誰かが型付き配列を使用してMD5を書き換えた場合、それを再訪するかもしれません。
コードは次のようになります。
HTML:
<input type="file" id="file-dialog" multiple="true" accept="image/*">
JS (w JQuery)
$("#file-dialog").change(function() {
handleFiles(this.files);
});
function handleFiles(files) {
for (var i=0; i<files.length; i++) {
var reader = new FileReader();
reader.onload = function() {
var md5 = binl_md5(reader.result, reader.result.length);
console.log("MD5 is " + md5);
};
reader.onerror = function() {
console.error("Could not read the file");
};
reader.readAsBinaryString(files.item(i));
}
}
spark-md5
および Q
最新のブラウザ(HTML5 File APIをサポート)を使用していると仮定すると、大きなファイルのMD5ハッシュの計算方法は次のとおりです(可変チャンクのハッシュ)
function calculateMD5Hash(file, bufferSize) {
var def = Q.defer();
var fileReader = new FileReader();
var fileSlicer = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
var hashAlgorithm = new SparkMD5();
var totalParts = Math.ceil(file.size / bufferSize);
var currentPart = 0;
var startTime = new Date().getTime();
fileReader.onload = function(e) {
currentPart += 1;
def.notify({
currentPart: currentPart,
totalParts: totalParts
});
var buffer = e.target.result;
hashAlgorithm.appendBinary(buffer);
if (currentPart < totalParts) {
processNextPart();
return;
}
def.resolve({
hashResult: hashAlgorithm.end(),
duration: new Date().getTime() - startTime
});
};
fileReader.onerror = function(e) {
def.reject(e);
};
function processNextPart() {
var start = currentPart * bufferSize;
var end = Math.min(start + bufferSize, file.size);
fileReader.readAsBinaryString(fileSlicer.call(file, start, end));
}
processNextPart();
return def.promise;
}
function calculate() {
var input = document.getElementById('file');
if (!input.files.length) {
return;
}
var file = input.files[0];
var bufferSize = Math.pow(1024, 2) * 10; // 10MB
calculateMD5Hash(file, bufferSize).then(
function(result) {
// Success
console.log(result);
},
function(err) {
// There was an error,
},
function(progress) {
// We get notified of the progress as it is executed
console.log(progress.currentPart, 'of', progress.totalParts, 'Total bytes:', progress.currentPart * bufferSize, 'of', progress.totalParts * bufferSize);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.4.1/q.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/spark-md5/2.0.2/spark-md5.min.js"></script>
<div>
<input type="file" id="file"/>
<input type="button" onclick="calculate();" value="Calculate" class="btn primary" />
</div>
JSでファイルシステムにアクセスできないことは別として、クライアントが生成したチェックサムにはまったく信頼を置きません。したがって、どのような場合でも、サーバーでチェックサムを生成することは必須です。 –トマラック2009年4月20日14:05
ほとんどの場合、これは役に立ちません。 MD5をクライアント側で計算し、サーバー側で再計算されたコードと比較して、異なる場合はアップロードが失敗したと結論付けることができるようにします。私は、破損していないファイルを受信することが重要である科学データの大きなファイルを扱うアプリケーションでそれを行う必要がありました。私のケースはシンプルで、ユーザーはデータ分析ツールからMD5をすでに計算しているため、テキストフィールドを使用してユーザーに尋ねるだけでした。
ファイルのハッシュを取得するには、多くのオプションがあります。通常、問題は大きなファイルのハッシュを取得するのが本当に遅いことです。
ファイルのハッシュを取得する小さなライブラリを作成しました。64kbのファイルの先頭と64kbのファイルの末尾です。
ライブの例: http://marcu87.github.com/hashme/ およびライブラリ: https://github.com/marcu87/hashme
インターネットには、MD5ハッシュを作成するためのスクリプトがいくつかあります。
Webtoolkitからのものは良いです、 http://www.webtoolkit.info/javascript-md5.html
ただし、アクセスが制限されているため、ローカルファイルシステムにアクセスできるとは思いません。
現在のHTML5では、バイナリファイルのmd5ハッシュを計算できるはずですが、その前の手順は、バナリーデータBlobBuilderを文字列に変換することだと思います。この手順を実行しようとしていますが、成功していません。
私が試したコードは次のとおりです。 HTML5 JavascriptでBlobBuilderを文字列に変換する