2012-04-13 3 views
2

Недавно я пытался выяснить самый быстрый способ сравнить два больших XML-документа и рекомендацию по совместному использованию хэширования, а затем просто сравнить хэш-строки.Использование MD5/SHA1 для сравнения экземпляров XML

Сначала это казалось очевидной/блестящей идеей! Но потом что-то инстинктивно сказал мне, что это может быть «слишком хорошо, чтобы быть правдой».

Точно так же, как сериализация POJO для сравнения/клонирования широко рассматривается как «плохая практика», то же самое верно для этого technqiue? Почему или почему нет? Предостережения/подводные камни и т. Д.?

+0

рискует казаться тупым, это действительно зависит от того, почему вы хотите провести сравнение. например: для системы резервного копирования, в которой вам необходимо записывать изменения, тогда принятие хэша в порядке. просто для того, чтобы знать, являются ли два файла одинаковыми или разными, байт для сравнения байтов может быть очень быстрым (каждый первый байт отличается от другого), тогда как что-то вроде [Rabin-Karp] (http: //en.wikipedia. org/wiki/Rabin-Karp_string_search_algorithm) - O (n) – violet313

ответ

5

Позвольте мне начать с того, что сравнение XML сложнее. Это сложно, потому что, поскольку вы очень хорошо выразились в названии своего вопроса, вы сравниваете экземпляры XML.

XML - это не только контент (текстовые файлы, двоичные файлы и т. Д.), Которые вы можете сравнить, чтобы увидеть, чем-то отличается; XML имеет смысл, и разные экземпляры XML могут иметь одинаковое значение.

Например, рассмотрим этот XML-образец:

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

Это отличается от этого?

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

или это:

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

или даже это ?:

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

Ответ заключается в том, что образцы все равны. Но если вы хэш каждый из них, вы будете получать разные хеши каждый раз.

Если вы хотите использовать хэш-примеры XML и использовать хэш для сравнения, сначала вы должны получить их в a canonical form. Если XML не часто меняются, вы можете сохранить хэш вдоль стороны XML, а затем просто сравнить хэши. Вы вычисляете дайджест сообщения только тогда, когда что-то меняется. Это может быть очень быстро.

Другим решением будет также преобразование an XSLT и использование двух экземпляров XML в качестве входных данных. Затем вы выводите что-то более простое (возможно, плоский файл со всеми именами и атрибутами элементов и атрибутов), которые проще сравнивать.

Есть lots of ways to compare XML файлов и как @ violet313, упомянутых в комментарии, это действительно зависит от того, почему вы хотите провести сравнение и что именно вы хотите сравнить.

+0

Я ценю отличный ответ! Оглядываясь назад, я должен был упомянуть в своем сообщении, что экземпляры XML генерируются XStream, поэтому одни и те же POJO будут преобразованы в один и тот же XML и * should *, если я не пропущу что-либо карту для тех же хешированных значений. Поэтому я не думаю, что это проблема для нас - но очень хорошо сделано! – IAmYourFaja

1

Вычисление хешей требует чтения всех файлов в любом случае и тратит процессорный цикл на его вычисление, поэтому почему бы не сравнить байты с байтом, если вас не беспокоят, что файлы отличаются друг от друга, но семантически идентичны?

Также оба хеша, которые вы указали, имеют проблемы (MD5 более) и не должны использоваться, если есть риск, что у кого-то может быть стимул для создания документов, имеющих тот же самый хеш, все же отличающийся (это легко выполнимо с MD5 который полностью нарушен с криптографической точки зрения и, возможно, недалеко от SHA1).

В основном то, что вы предлагаете (хеширование, а затем сравнение хэшей), скорее всего медленнее, чем простое сравнение (если вы не читаете от истинного искания СМИ) и имеют свои проблемы. Это и в контексте XML-документов, скорее всего, вы хотите использовать более высокий уровень подхода, так как Богдан в значительной степени гвоздит его.