2012-04-13 7 views
2

Ich habe kürzlich versucht, den schnellsten Weg zu finden, zwei große XML-Dokumente zu vergleichen, und ein Kollege empfahl, sie zu hashen und dann die Hash-Strings zu vergleichen.Verwenden von MD5/SHA1 zum Vergleichen von XML-Instanzen

Zuerst schien dies eine offensichtliche/brillante Idee! Aber dann sagte mir etwas instinktiv, dass es "zu gut wäre, um wahr zu sein".

Genauso wie Serialisierung von POJOs zum Vergleich/Klonen allgemein als "schlechte Praxis" angesehen wird, gilt das auch für diese Technik? Warum oder warum nicht? Vorbehalte/Fallstricke usw.?

+0

auf das Risiko, stumpf zu klingen, kommt es wirklich darauf an, warum Sie einen Vergleich machen wollen. zB: Für ein Backup-System, in dem Sie Änderungen aufzeichnen müssen, ist die Übernahme eines Hashes in Ordnung. um nur zu wissen, ob zwei Dateien gleich oder verschieden sind, kann ein Byte-für-Byte-Vergleich sehr schnell sein (oops! erstes Byte ist anders. Stopp hier), während etwas wie [Rabin-Karp] (http: //en.wikipedia. org/wiki/Rabin-Karp_string_search_algorithm) ist O (n) – violet313

Antwort

5

Lassen Sie mich zunächst sagen, dass XML-Vergleich ist schwierig. Es ist schwierig, weil Sie XML-Instanzen vergleichen, wie Sie es im Titel Ihrer Frage sehr gut sagen.

XMLs sind nicht nur Inhalte (Textdateien, Binärdateien usw.), die Sie vergleichen können, um festzustellen, ob sich etwas unterscheidet. XML hat eine Bedeutung und verschiedene XML-Instanzen können dieselbe Bedeutung haben.

Betrachten wir zum Beispiel diese XML-Beispiel:

<sample a="foo" b="bar" /> 

Ist das anders als das?

<sample b='bar' a='foo' /> 

oder dies:

<sample 
a="foo" 
b="bar" /> 

oder sogar ?: diese

<sample a="foo" b="bar"></sample> 

Die Antwort ist, dass die Proben alle gleich sind. Aber wenn Sie jedes Hashing durchführen, erhalten Sie jedes Mal andere Hashes.

Wenn Sie XML-Instanzen hashen und den Hash zum Vergleich verwenden möchten, müssen Sie sie zuerst in a canonical form abrufen. Wenn sich die XML-Dateien nicht häufig ändern, können Sie den Hash-Wert neben dem XML-Code speichern und dann Hashwerte vergleichen. Sie berechnen den Nachrichtenauszug nur, wenn sich etwas ändert. Dies kann sehr schnell sein.

Eine andere Lösung wäre auch, an XSLT Transformation zu haben und die zwei XML-Instanzen als Eingabe zu verwenden. Sie geben dann etwas einfacheres aus (vielleicht eine flache Datei mit allen Element- und Attributnamen und -werten), die einfacher zu vergleichen ist.

Es gibt lots of ways to compare XML Dateien und wie @ violet313 im Kommentar erwähnt, kommt es wirklich darauf an, warum Sie einen Vergleich machen wollen und was genau Sie vergleichen möchten.

+0

Ich schätze die tolle Antwort! Im Nachhinein hätte ich in meinem Post erwähnen sollen, dass die XML-Instanzen von XStream generiert werden, also werden die gleichen POJOs in die gleiche XML konvertiert, und * sollte *, es sei denn, ich vermisse etwas Map mit den gleichen Hash-Werten. Also denke ich nicht, dass dies ein Problem für uns ist - aber sehr gut gemacht! – IAmYourFaja

1

Die Berechnung der Hashes erfordert sowieso das Lesen der gesamten Dateien und verbringen CPU-Zyklus, es zu berechnen, also warum nicht Byte-zu-Byte-Vergleich tun, wenn Sie nicht besorgt über die Dateien sind unterschiedlich, aber semantisch identisch?

Auch der von Ihnen zitierte Hash hat Probleme (MD5 mehr) und sollte nicht verwendet werden, wenn das Risiko besteht, dass jemand einen Anreiz hat, Dokumente mit demselben Hash zu erstellen, die unterschiedlich sind (dies ist mit MD5 problemlos möglich) was aus kryptographischer Sicht völlig kaputt ist und möglicherweise nicht weit entfernt mit SHA1).

Grundsätzlich was Sie vorschlagen (Hashing dann vergleichen Sie die Hashes) ist wahrscheinlich langsamer als einfach vergleichen (es sei denn, Sie lesen von einem wirklich suchen abgeneigtes Medium) und haben eigene Probleme. Das und im Zusammenhang mit XML-Dokumenten wünschen Sie sich wahrscheinlich einen Ansatz auf höherer Ebene, da Bogdan es ziemlich genau auf den Punkt bringt.

Verwandte Themen