
___________
In diesem Tutorial will ich euch zeigen, wie ihr die HTML 5 File API benutzen könnt, um MD5, SHA1, SHA256 und SHA512-Summen nur mit JavaScript zu erzeugen.
Ihr braucht nur einen Editor, einen aktuellen Browser und gute JavaScript-Kenntnisse.
Der ganze Code funktioniert bei mir getestet mit Google Chrome 13, Opera 11.50 und Firefox 6.02. Aber leider (noch) nicht mit Safari 5.1 und Internet Explorer 9.
Nun, zuerst bauen wir uns ein ganz normales HTML-Grundgerüst mit einem Dateifeld, Auswahlfeld, einer Statusanzeige und einem Ausgabefeld:
HTML-Code:
<!doctype html> <html> <head> <script type="text/javascript" src="md5.js"></script> <script type="text/javascript" src="sha1.js"></script> <script type="text/javascript" src="sha256.js"></script> <script type="text/javascript" src="sha512.js"></script> <script type="text/javascript" src="file_md5.js"></script> <meta charset="utf-8" /> <title>Checksums with HTML5 File API</title> </head> <body> <h1>Checksums with HTML5 File API</h1> <hr /> <select id="hash_func"> <option value="md5">MD5</option> <option value="sha1">SHA1</option> <option value="sha256">SHA256</option> <option value="sha512">SHA512</option> </select> <input type="file" id="file_input" multiple="multiple" /> <hr /> <span id="status">Status: Select files!</span> <output> <ul id="md5-list"> </ul> </output> </body> </html>
Nun seht ihr bereits, dass ich mehrere JavaScript-Dateien eingebunden haben. Die ersten vier beinhalten eine JavaScript-Implementierung der Hash-Funktionen von Paul Johnston (http://pajhome.org.uk/crypt/md5/, BSD-Lizenz).
Die letzte Datei wird unseren eigenen Code beinhalten.
Zuerst müssen wir einen OnChange-Eventhandler zum Dateifeld hinzufügen (-->file_md5.js):
Code javascript:
1 2 3 4 | window.onload = function()
{
document.getElementById("file_input").onchange = handleFileSelect;
} |
Aber wie greifen wir jetzt auf die ausgewählten Dateien zu?
Dazu gibt es das Array files als Eigenschaft des Dateifeldes:
Code javascript:
1 | var files = input.files; |
Jedes Objekt des Arrays enthält laut W3C die Eigenschaften name, size, type und lastModifiedDate. Außerdem gibt es noch die Funktion slice, welche die Daten anhand der Paramter start und length zerstückeln kann.
Allerdings enthält z.B. Chrome zusätzliche Werte:
- fileSize
- webkitRelativePath
- fileName
- webkitSlice
Jetzt werden wir uns eine Funktion bauen, die mit mithilfe eines FileReader eine Datei binär einliest und zurückgibt. Dafür brauchen wir zuerst ein Objekt davon:
Code javascript:
1 2 3 | function readFile(file, callback)
{
var reader = new FileReader(); |
Code javascript:
1 2 3 4 5 6 | reader.onload = function(evt)
{
document.getElementById('status').innerHTML = "Ready";
if (typeof callback=="function")
callback(file, evt);
}; |
Dann setzen wir noch zwei andere Eventhandler: onprogress und onerror.
Ersterer ist - wie der Name schon sagt - für den Updateprozess verantwortlich und Zweiterer für eventuelle Fehler. Allerdings habe ich festgestellt, dass onprogress nie in Google Chrome und Firefox aufgerufen wird.
Code javascript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /* Innerhalb der Funktion */
reader.onprogress = updateProgress;
reader.onerror = errorHandler
/* Außerhalb der Funktion */
function updateProgress(evt)
{
document.getElementById('status').innerHTML = "Status: Processing";
}
function errorHandler(evt)
{
document.getElementById('status').innerHTML = "Status: Error ("+evt.target.error.code+")";
} |
Und zum Schluss unserer readFile()-Funktion werden wir die Leseaktion in Gang setzen:
Code javascript:
1 2 | reader.readAsBinaryString( file );
} |
Nun kommen wir zum anderen Teil: dem Hashen des Dateiinhalts und Anzeige
Da wir eine Mehrfachauswahl zugelassen haben (multiple im Input-Tag), müssen wir erstmal alle Dateien durchlaufen. Und dies erledigen wir in der Funktion handleFileSelect(), die wir oben erwähnt haben:
Code javascript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | function handleFileSelect()
{
var input = document.getElementById("file_input");
if ( typeof FileReader=="undefined" || !input.files)
{
alert("Your browser doesn't support the HTML 5 File API!");
return;
}
for (var i=0; i < files.length; i++)
{
readFile(input.files[i], function(file, evt)
{
var hash = null;
var hash_function = document.getElementById("hash_func").value;
/* Dateiinhalt hashen (je nach Auswahl in der Selectbox) */
if (hash_function=="md5") hash = hex_md5( evt.target.result );
else if (hash_function=="sha1") hash = hex_sha1( evt.target.result );
else if (hash_function=="sha256") hash = hex_sha256( evt.target.result );
else if (hash_function=="sha512") hash = hex_sha512( evt.target.result );
/* Als HTML per DOM-Funktionen ausgeben */
var elListItem = document.createElement("li");
var elFilename = document.createTextNode( file.name + " ("+hash_function.toUpperCase() +")" );
var elMD5 = document.createTextNode( hash );
elListItem.appendChild( elFilename );
elListItem.appendChild( document.createElement("br") );
elListItem.appendChild( elMD5 );
document.getElementById("md5-list").appendChild( elListItem );
});
}
} |
Danach - wie gesagt - durchlaufen wir das Datei-Array.
Danach wird die Funktion readFile aufgerufen und ihr werden als Paramter zuerst die aktuelle Datei und danach eine Callback-Funktion übergeben.
Die Kernaufgabe der Callback-Funktion ist einfach die ausgewählte Hash-Methode zu ermitteln, mit dieser zu hashen und das Ergebnis als HTML auszugeben.
Das wars! Ich hoffe euch hat das Tutorial gefallen und ich würde mich über Kommentare und Kritik freuen

Im Anhang findet ihr zusätzlich zu den Dateien auch noch einen Ordner test, in dem Dateien zum testen sind (der Hash im Dateinamen sollte dem Ausgabe-Hash entsprechen).
ComFreek





Bereiche
Kategorien
Forum - Webmaster & Internet




