惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
U
Unit 42
Vercel News
Vercel News
Martin Fowler
Martin Fowler
云风的 BLOG
云风的 BLOG
爱范儿
爱范儿
MongoDB | Blog
MongoDB | Blog
J
Java Code Geeks
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
C
Check Point Blog
N
Netflix TechBlog - Medium
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
博客园_首页
WordPress大学
WordPress大学
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
IT之家
IT之家
Last Week in AI
Last Week in AI
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
V
Visual Studio Blog
小众软件
小众软件

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
Аудит алгоритмов: как реализация Boyer-Moore с 190K звёзд...
Владислав Попов · 2026-06-22 · via Все публикации подряд на Хабре

Средний

3 мин

0

В 2015 году группа исследователей (Flouri et al.) решила проверить реализации классического алгоритма Готоха (1982) для выравнивания биологических последовательностей. Из 10 проверенных реализаций только 2 давали правильный результат. 8 из 31 учебных материалов содержали математическую ошибку.

Я решил проверить, насколько это типично для других классических алгоритмов. Начал с Boyer-Moore (1977), одного из самых известных алгоритмов поиска подстроки.

Методология

Написал тестовый фреймворк, который проверяет любую реализацию поиска подстроки против brute-force эталона:

  • 35 статических тестов: пустые строки, перекрывающиеся совпадения, периодические строки, pattern == text

  • Property-based случайные тесты (8000+ на реализацию): полнота (все совпадения найдены), корректность (нет ложных срабатываний), порядок, количество

  • Разные распределения: маленький/большой алфавит, бинарные строки, длинные паттерны

Находка 1: TheAlgorithms/Python (190K+ звёзд)

Самый популярный образовательный репозиторий алгоритмов на GitHub. Файл strings/boyer_moore_search.py.

Метод bad_character_heuristic() пытается использовать правило плохого символа для пропуска позиций. Но сдвиг записывается в переменную цикла for:

for i in range(self.textLen - self.patLen + 1):
    mismatch_index = self.mismatch_in_text(i)
    if mismatch_index == -1:
        positions.append(i)
    else:
        match_index = self.match_in_pattern(self.text[mismatch_index])
        i = (mismatch_index - match_index)  # мёртвый код

В Python переприсвоение переменной for-цикла не влияет на следующую итерацию. for i in range(N) всегда берёт следующее значение из range(), игнорируя любые изменения i внутри тела цикла.

Я добавил счётчик итераций:

Текст: 32 символа, Паттерн: 4 символа
Итераций выполнено: 29 (= brute-force)
Рабочий Boyer-Moore: ~8 итераций

Алгоритм выдаёт правильные результаты, поэтому все тесты проходят. Но работает за O(nm) вместо O(n/m). Каждый, кто скопировал этот код, думает что у него Boyer-Moore, а на самом деле имеет наивный поиск с лишними вычислениями.

Исправление тривиальное: заменить for на while.

Находка 2: бесконечный цикл при pattern == text

Типичная реализация полного Boyer-Moore (с обоими правилами: bad character + good suffix) зависает на тривиальном входе search("abc", "abc").

Причина: при полном совпадении индекс i декрементируется на m позиций (с m-1 до -1). Затем good_suffix[0] сдвигает i ровно на m назад. i возвращается на исходную позицию. Цикл бесконечен.

Находка 3: оригинальная статья 1977 года содержала ошибку

Boyer и Moore опубликовали алгоритм в 1977 году, но не включили корректный алгоритм вычисления таблицы good suffix (delta2). Первый правильный алгоритм дал Войцех Ритер (Rytter) в 1980 году, через 3 года.

Эта ошибка продолжает распространяться. В 2019 году Microsoft исправляла баги в std::boyer_moore_searcher (C++17 STL), связанные именно с отсутствием Rytter correction.

Масштаб проблемы

Это не уникальная ситуация. Классические алгоритмы копируются между учебниками, лекциями и GitHub-репозиториями без верификации. Ошибки в оригинальных статьях распространяются десятилетиями.

Я составил список из 35 алгоритмов в 6 категориях (биоинформатика, численные методы, графы, сортировки, строки, вычислительная геометрия) для систематического аудита. Следующая цель: BLAST (1990), самый используемый инструмент биоинформатики. Формального аудита его корректности не существует, несмотря на 35 лет использования.

Код

Тестовый фреймворк и все результаты: https://github.com/devladpopov/algorithm-autopsy

Issue в TheAlgorithms/Python: https://github.com/TheAlgorithms/Python/issues/14844

Если знаете о подобных багах в классических алгоритмах, буду рад обсудить.