Thursday, July 14, 2011

BSD diff

Исправляя проблему в rspamd с неверным рассчетом "похожести" частей в мультипарте, решил заменить вычисление расстояния Левенштейна на поиск максимальной общей подстроки - алгоритм, используемый в diff. В итоге нашел алгоритм под MIT лицензией (практически аналогичной BSD), который мне и подошел: http://www.ioplex.com/~miallen/libmba/dl/src/diff.c
После небольших изменений под glib (например, использование GArray) я написал тест для сравнения с вычислением расстояния Левенштейна. Для коротких текстов разница в скорости практически незначительна, но уже на 20кб тексте расстояние Левенштейна считалось 8 секунд, а diff алгоритм выполнился за 8 миллисекунд, что вполне приемлимо для работы.
Теперь пытаюсь найти алгоритм для вычисления нечеткой сигнатуры для письма. Используемый сейчас алгоритм - производная от ssdeep - очень плохо устойчив к сдвигам внутри текста. Любой сдвиг гарантированно разбивает несколько участков сигнатуры. Кроме этого, есть задача сокращения размерности сигнатуры (сейчас это 64 символа) для того, чтобы искать сигнатуру по KD-дереву, которое опять же плохо работает для больших размерностей (неэффективно как в плане памяти, так и в плане нахождения похожих элементов).

No comments:

Post a Comment