Hash-It, und das Dirty-Bit fällt weg

In der letzten Episode unserer Daily-Soap “Gute APIs, Schlechte APIS” sahen Sie:

Aufruhr in der Editoren-Straße! Großmutter Textbox zeigte erste Anzeichen für Demenz, als ihr Schwiegersohn Updatetimer sie nach der aktuellen Cursorposition fragte. Während dessen plagen Familienvater Streamwriter schwere Gewissensbisse, nachdem er heimlich mit seiner Jugendfreundin UTF-16 fremd gegangen war, während seine angetraute UTF-8 zu Hause saß und den kleinen ANSI-Codec stillte. Parallel kam es zu einer Schlägerei zwischen dem pubertierenden Jungen ToolBar, der mit seinem Zimmergenossen MenuBar um seine ID-Zuordnung im Streit lag. Und während alle ihren Problemen nachgehen, beobachtet Professor Statemanager distanziert und dennoch mit Sorge, wie sich Grußmutter Textbox’ Gesundheitszustand verändert.


Tja, man kann auch an einem simplen Texteditor ein Weilchen sitzen, vor allem wenn man damit sein gerade neu hingeklatschtes UI-Framework testet und debugt. Doch um diese Kleinigkeiten soll es heute nicht gehen.

In der Vergangenheit nutzte ich bei Editierungsvorgängen gerne ein “Dirty-Bit”, welches nach dem Laden von Daten oder nach dem Speichern auf 0 gesetzt wird, und beim ersten Tastendruck auf 1 geändert wird.

So kann dann beim Schließen oder weiterem Öffnen ein Dialog angezeigt werden, dass sich Daten geändert haben und der Benutzer entscheiden soll, ob er vorher die Anpassungen speichern will.

Doch ganz korrekt ist das nicht, denn wenn man nach dem Laden versehentlich eine Taste drückt und diese im Nachhinein wieder löscht bzw. rückgängig macht, haben wir ein gesetztes Dirty-Bit obwohl der Text gar nicht mehr “dreckig” ist.

Sinnvoller wäre eine Vergleich, ob der Originaltext mit dem aktuellen Text übereinstimmt … doch dann haben wir bei großen Dokumenten den doppelten Speicherverbrauch.

Die Lösung: Hashes

Hashfunktionen, umgangssprachlich gerne zu “Prüfsummen” degradiert, sollen einen Datensatz in eine kurze Bytefolge abbilden, die möglichst eindeutig ist.
Die erwähnten “Prüfsummen” (z.B. Buchstabensummen) würden zu häufig die gleichen Ergebnisse bei ungleichem Ausgangsmaterial liefern, weshalb Hashes mathematisch so gestrickt sind, dass es nur extrem selten vorkommt, dass aus zwei ungleichen Quellen der gleiche Hash-Wert entsteht.

MD5 ist einer der ältesten und bekanntesten Hash-Algorithmen und wir finden im Netz häufig bei Downloads einen Hash, damit man nach dem Herunterladen bei seiner Kopie schnell vergleichen kann, ob auch alle Bits richtig angekommen sind.
Denn wenn auch nur ein Bit verändert wäre, würden die Hashes nicht mehr übereinstimmen.

SHA-1 ist etwas komplexer und länger (und damit auch sicherer) als MD5, und löste MD5 schrittweise ab, während SHA-2 (häufig in der Form von SHA-256) noch länger und damit noch sicherer ist und in vielen modernen Produkten zum Einsatz kommt.

Warum also das Ganze nicht durch Hashes lösen?

Immer wenn Dokumente geladen werden, wird ein Hash generiert und gespeichert. Denn auf diese paar Bytes kommt es nicht an. Wird das Dokument geschlossen oder ein neues geöffnet, wird ein Hash über den aktuellen Text gebildet und im Falle von Ungleichheit der berühmte “Wollen Sie speichern?”-Dialog angezeigt.

Der Vorteil dabei ist, dass wir jetzt darauf verzichten können Tastenanschläge zu beobachten und nur bei ändernden Tasten das Dirty-Bit zu pflegen, es gibt ja auch Tasten wie Nach-Oben oder Nach-Unten, die nichts ändern und zusätzlich ausgefiltert werden müssten.

Der einzige Nachteil bestünde bei sehr großen Dokumenten auf langsamen Maschinen, wo das Generieren der Hashes merkbar Zeit in Anspruch nimmt.

Doch bei Texteditoren ist das extrem unwahrscheinlich.
Oder kennen Sie jemanden, die Textdateien mit über 50 Megabytes bearbeitet?

Fazit

Hashes sind eine tolle Sache und nicht nur für Dateivergleiche nach Downloads interessant. Man kann sie auch in der Anwendungsentwicklung einsetzen um Byte-für-Byte-Vergleiche größerer Datenblöcke zu beschleunigen.