Обновить
128K+

Алгоритмы *

Все об алгоритмах

262,23
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Как мы защищаем номера телефонов с помощью Oblivious Pseudorandom Function

Время на прочтение9 мин
Охват и читатели5.9K

По новому требованию закона онлайн-кинотеатры и другие аудиовизуальные сервисы должны передавать уполномоченной правительством исследовательской организации дополнительный идентификатор пользователя, сопоставленный с номером мобильного телефона. Если один человек указал один и тот же номер в разных сервисах, идентификатор тоже должен совпасть.

На первый взгляд, задача элементарная: нормализовать номер телефона и посчитать от него хеш с общим для всех компаний секретом. На практике простое решение создало бы единый секрет сразу для десятков независимых компаний — и единую точку компрометации. Поэтому мы хотели найти более надёжный способ защитить данные пользователей.

Меня зовут Айдар Сабиров, я занимаюсь информационной безопасностью в Яндексе. Порой нам приходится решать самые необычные задачи, в которых техническая часть оказывается лишь половиной решения. Вторая половина — договориться между компаниями и превратить непонятные формулы в работающий отраслевой процесс. Это как раз такой случай. 

В этой статье я расскажу Хабру, как мы вместе с другими участниками рынка искали более надёжную конструкцию и пришли к схеме на основе Oblivious Pseudorandom Function (OPRF), предотвращающей отслеживание пользователя по его номеру.

Читать далее

Новости

664 тысячи книг, десятки агентов — и ни одной метрике нельзя верить

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели5K

Мне нужны собственные каноники книг. Каноник — это одна устойчивая запись «вот этот текст», к которой привязывается всё остальное: файлы в разных форматах, аудиокниги, издания, дубли.

Не потому, что внешние источники плохие. Если мне нужно быстро получить автора, название или идентификатор книги, я вполне могу взять их из существующего каталога. Даже если в каталоге есть мусор, это не катастрофа: мусор можно постепенно исправлять. Проблема в другом — это не мой каталог. Я могу годами накапливать вокруг внешнего идентификатора результаты собственных анализаторов: связывать с ним аудиокниги, находить дубли, определять издания, собирать статистику, строить рекомендации. А потом внешний источник поменяет идентификаторы, структуру или просто исчезнет, и вся накопленная работа повиснет в воздухе.

Поэтому я решил сделать собственный корпус книг. Он тоже будет грязным, и это нормально. Главное, что это мой грязный корпус: я могу его постепенно улучшать, и его идентификаторы контролирую я сам.

В корпусе сейчас около 664 тысяч книг. А задача, ради которой всё это понадобилось, на первый взгляд была совсем простой: взять несколько минут аудиокниги, прогнать через Whisper и найти соответствующую книгу по тексту.

Ну что может быть сложного? Оказалось — примерно всё.

Читать далее

Кому принадлежит рыбка: задача Эйнштейна с точки зрения оптимизации

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели4.8K

«Только 1% людей способны решить эту задачу». С такой подписью в школьные годы мне попалась задача Эйнштейна. На подобную наживку я тогда клевал без раздумий и решал честно, как велели правила: в уме, без бумаги, 40 минут на всё. Сегодня решу её так, как меня научили годы работы с оптимизацией.

Читать далее

AI‑Evolution: перенёс симулятор цифровых сущностей с React + Python на Unity

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели3.8K

В прошлом посте я писал о том что создаю ИИ‑песочницу на React + Python. С тех пор многое обдумал и многое переосмыслил и все‑таки пришел к мысли, что выбрал неудачный стек для такого проекта. Напомню для контекста: я занимаюсь разработкой эволюционного симулятора, где агенты (скажем так, цифровые животные) бегают по полю, живут и взаимодействуют с окружением не на основе жёсткого дерева условий («если‑то»), а под управлением нейросетей.

Читать далее

Lock‑free по нарастающей

Уровень сложностиСложный
Время на прочтение16 мин
Охват и читатели10K

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

В качестве панацеи предлагают lock-free структуры, но и тут полно ловушек — банальный регулярный вызов ядра SetEvent способен сжечь весь выигрыш от lock-free. Сами алгоритмы lock-free порой тяжеловесны, не всегда предлагают удачный trade-off и даже не всегда уместны. Но что ещё хуже: будучи применёнными без должной тщательности, они могут не только не дать выигрыша, но даже навредить.

В этой статье мы разберём устройство нескольких базовых объектов библиотеки wxl и познакомимся с концепцией «алгоритм дешевеет под нагрузкой». Мы пройдём путь от трёх базовых инструкций процессора до готового канала, разберём, как продление release-последовательности спасает от ABA, как ленивые триггеры arm/disarm позволяют будить поток только тогда, когда он реально спит, и как заставить данные летать между ядрами без обращений к операционной системе.

Готовы? Приступаем...

Английский я не слышу двадцать лет. Португальский услышал за два…

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели7.9K

Эта статья выросла из спора под прошлой: можно ли за месяц научиться различать китайские звуки или только узнавать выученные фразы. Спор про китайский, а суть — про то, как вообще учишься распознавать чужие звуки. Об этом ниже, в конце — пари.

Двадцать лет использую английский и работаю на нём каждый день. И до сих пор его не слышу — точнее, слышу выборочно. Рабочие созвоны понимаю почти полностью, хоть с американцем, хоть с индусом: тема знакомая, слова предсказуемые. А вне работы всё решает, кто говорит: русских коллег на английском разбираю идеально, немцев — хорошо, китайцев — с трудом, американских блогеров — два ролика из десяти, фильмы — три.

Португальский — два года. Улицу, соседей, родительские собрания — на шесть из десяти.

Я не думаю, что португальский проще. Я думаю, что английский я двадцать лет учил не тот. И понял это, когда год учил не тот португальский.

Сразу уточню, о чём речь. Не о понимании — о распознавании звуков. То, что я могу прочитать фразу на бумаге и понять, ничего не говорит о том, разберу ли я её в речи.

Откалибровать слух

Что скрывают в себе меры расстояния: от kNN и k‑means до стилометрии

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели7.3K

Представим, что kNN отнес новую точку к некоторому ближайшему классу. Все просто и знакомо. Однако привычная схема скрывает интересную недосказанность. Какие именно признаки сделали выбранный класс ближе? Возможно, почти всю разницу дал сигнал от одной координаты, возможно это вклад весьма конкретного набора координат, который можно интерпретировать как устойчивый признак более высокого порядка, а может, эти вклады распределены почти равномерно? На самом деле ответить на вопросы выше довольно легко. Для этого достаточно сохранить слагаемые, из которых получилось расстояние, перед тем, как «затирать» их суммированием.

Читать далее

Пишем трассировщик лучей на Brainfuck

Время на прочтение9 мин
Охват и читатели10K

В процессе подготовки к соревнованиям по системному программированию на C++ я начал заново изучать CMake, потому что Cargo сильно меня избаловал. При этом я заметил в туториале интересное утверждение:

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

CMake Language Fundamentals

Я раньше писал трассировщик лучей и переписывал его под GPU, поэтому это заявление привлекло моё внимание и заставило задуматься, на каком же ещё языке лучше писать такой трассировщик.

Для последней версии я писал код, почти не связанный с базовыми алгоритмами и в основном зависевший от довольно сложного набора API. Поэтому я выбрал самый простой из известных мне языков — Brainfuck, ведь простота языка очевидным образом приводит к созданию простой кодовой базы. На самом деле, кодовые базы на BF обычно состоят всего из нескольких строк. Кроме того, комментарий Урбана Мюллера в README заставил меня написать контрпример.

Код выложен на Github.

Читать далее

Синхронизация камер по звуку без хлопушки: что я понял, пока делал плагин для Premiere Pro с нейросетью

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели5.3K

Я монтажер, не программист. За месяц вместе с нейросетью сделал плагин для Premiere Pro: он синхронизирует камеры с рекордером по звуку, режет паузы и дубли и собирает секвенцию. Историю я уже рассказывал на vc.ru, а здесь будут внутренности: как найти сдвиг между файлами, почему одного порога корреляции мало, как отличить готовый ролик от исходника и почему тесты на каждый релиз оказались важнее любого кода.

Сразу оговорюсь: код писала нейросеть под мою постановку, а я проверял на своих проектах. Поэтому это не статья «смотрите, как красиво». Это статья про задачи, которые пришлось решить, грабли, на которые наступил, и числа, которые пришлось намерить.

Читать далее

Pillow для обработки изображений: все фильтры от А до Я

Время на прочтение8 мин
Охват и читатели11K

Это вторая часть разбора библиотеки Python Pillow. В прошлой статье был сделан упор на общее направление и примеры, теперь же давайте разберём конкретный инструментарий: отвечу на вопросы, что вообще можно использовать и каким образом. Можно назвать это так: прошлая статья – введение в ремонт, эта – хранилище инструментов. Стоит учесть, что всю более подробную информацию можно найти в сети, а с целями (зачем, для чего) придётся определяться самим. Впрочем, это и так очевидно.

Вся суть, благодаря которой нога моя ступила на территорию Pillow, можно описать следующим образом: желание автоматизации однотипной обработки нескольких файлов подряд. Через Photoshop можно обработать одно фото, но если у вас есть определённый шаблон, придётся долго возиться с каждым отдельным изображением. Нужен был инструмент, который был бы достаточно гибким, чтобы при желании и менять параметры, и создавать из последовательностей – функции. Таким инструментом оказалась библиотека Python, форк PIL, – Python Pillow.

Как и в программах для редактирования визуальных объектов данная библиотека работает по принципу фильтров: есть определённые фильтры, которые делают что-то с изображением, и можно задать определённое значение таким образом, чтобы указать программе, насколько сильно стоит это применить. И да, абсолютно весь тот шикарный визуал, который вы когда-либо видели в сети, был обработан, описан и создан именно по такой цепочке: ввод, наложение некоторых фильтров в каком-то соотношении, вывод.

Разобьём инструментарий на типы: равно как и отвёртки лежат отдельно от болтов... В Pillow есть три типа фильтров: готовые пресеты (те, что не требуют указания дополнительных значений), регулируемые фильтры (те, что требуют указания), и «ImageEnhance» (для регуляции контраста, яркости, резкости). Первые два типа объединены в единое семейство: «ImageFilter». Рассмотрим сначала их.

Читать далее

Конвейеры формирования изображений. Часть 3: Программная обработка изображения

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели7.1K

Всем привет! Это Егор Ершов, руководитель группы «Цветовая вычислительная фотография» в AIRI и заведующий сектором репродукции и синтеза цвета ИППИ РАН, и мы продолжаем разговаривать про конвейеры формирования изображений. Такие конвейеры запускаются каждый раз, когда вы нажимаете на кнопку спуска вашей камеры.

В первых двух статьях этого цикла мы в подробностях разобрали подготовку сырого RAW‑изображения: почитать про соответствующие шаги можно здесь и здесь. Их продуктом является картинка, приведённая к пространству стандартного наблюдателя. Это отправная точка для последующей обработки уже на программном уровне. Сегодня мы разберёмся, что происходит с ним дальше вплоть до сохранения изображения в памяти устройства в рамках того или иного стандарта сжатия — в качестве примера мы рассмотрим JPEG.

Приятного чтения!

Читать далее

Как работает инференс в больших языковых моделях

Время на прочтение14 мин
Охват и читатели7.9K

Привет, Хаброжители! Когда вы вводите промпт в большую языковую модель (LLM), машина преобразует ваш текст в числа, обрабатывает их, а потом возвращает ответ токен за токеном. В этой статье мы разберём, что такое инференс (логический вывод) в LLM и посмотрим, как он работает.

Читать далее

Дискретная диффузия: цепи Маркова с непрерывным временем

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели7K

Этот материал, задуманный как первый в серии статей о дискретных диффузионных моделях, уже несколько месяцев лежал у меня в черновиках. Выход модели Gemini Diffusion от Google показался мне отличным поводом наконец его опубликовать.

Цепи Маркова с дискретным временем — это последовательности случайных величин, в которых прошлое и будущее условно независимы при известном настоящем. Они достаточно хорошо известны в машинном обучении. А вот непрерывные аналоги этих цепей встречаются гораздо реже. Подобные модели фигурируют в исследованиях по дискретным диффузионным моделям (вот, вот и вот — далеко не полный список публикаций на эту тему). Поэтому мне показалось, что можно вернуться к блогу и написать о цепях Маркова с непрерывным временем, а может быть, и подготовить целый цикл публикаций. Пока же цель этого материала — сформировать у читателя интуитивное понимание того, как работают марковские цепи с непрерывным временем.

Читать далее

Ближайшие события

AGR.Checker: что нового в плагине для проверки ЦИМ перед сдачей в АГР

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели6K

Это продолжение истории про AGR.Checker — плагин для Revit, который мы с Андреем Прохоровым сделали для проверки ЦИМ на соответствие требованиям IDS перед сдачей в составе АГР. В прошлой статье я рассказывала про архитектуру, лицензирование и регистрацию программы в Роспатенте. С тех пор плагин поработал на реальных объектах, и почти всё новое в этой версии выросло из одного вопроса: «а почему вот это приходится проверять руками?»

Ниже — что мы добавили и какие инженерные задачи пришлось решить по дороге.

Экспорт в IFC с постобработкой

В конце прошлой статьи я обещала выгрузку IFC для последующей загрузки на СтроимПросто. Сделали.

Экспорт идёт через стандартное окно Revit: мы сознательно не стали собирать настройки экспорта программно. Недокументированные опции IFC-экспортёра вели себя по-разному в разных версиях Revit, и надёжнее оказалось дать пользователю привычное окно со своей конфигурацией и файлом маппинга.

Самое интересное начинается после экспорта. Плагин подписан на событие Revit о завершении экспорта и сразу же обрабатывает готовый IFC-файл:

Читать далее

Автоматизируем открытие файлов и проектов

Время на прочтение9 мин
Охват и читатели7.8K

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

Читать далее

Поиск по миллиону товаров на JavaScript: когда сжатый индекс проигрывает массиву

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели8.6K

На миллионе синтетических записей в Node.js сжатый индекс обогнал простое пересечение массивов примерно в пять раз — на запросах «редкое + частое». Но перебор редких кандидатов на Uint32Array оказался ещё вдвое быстрее. А поток postings на 9 МиБ удерживал в памяти весь файл на 137 МиБ из-за одной строки с subarray.

Читать далее

Построение карты проходимости на GPU по данным RGB-D камеры & лидара

Время на прочтение13 мин
Охват и читатели7.8K

Как построить карту проходимости для наземного робота на GPU, уложившись в 100мс лидара? Рассказываю путь от универсальной 3D-воксельной карты, которая не тянула даже на i7, до 2.5D-карты высот и расчётом уклонов прямо на CUDA. Плюс — почему RGB-D камера и лидар по отдельности не работают, а вместе дают плотный скан земли и препятствий.

Читать далее

От «быстрого JSON» к потоковой обработке данных: смена парадигмы в оценке производительности протоколов

Уровень сложностиСложный
Время на прочтение7 мин
Охват и читатели9.5K

Сразу хочу обозначить важный момент: эта статья не столько про пакет SilentJSON, сколько про схему работы с информацией, которую на его примере удалось реализовать и проверить на практике.

SilentJSON здесь – скорее инструмент и конкретная реализация идеи. Ту же архитектуру вполне можно реализовать самостоятельно, адаптировать под другой формат данных, другой язык или конкретные ограничения проекта. Она может получиться лучше или хуже SilentJSON, но главное – она может оказаться гораздо лучше приспособлена к реалиям конкретной задачи.

Читать далее

Какие наши продукты задевает эта CVE? Я продолжил заброшенный Minefield и нашёл, что он читал SBOM задом наперёд

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели8.8K

Выходит новость о критической уязвимости, и первый вопрос: какие из наших продуктов её тянут и что чинить первым? С 11 сентября 2026 года Cyber Resilience Act требует сообщать об активно эксплуатируемых уязвимостях в течение 24 часов, так что вопрос получил срок.

Под него хорошо подходил Minefield — граф SBOM на roaring bitmaps от BitBom, заархивированный в 2025 году. Я продолжил его под именем Sapper, добавил отчёт с приоритетами по CISA KEV и EPSS и по дороге нашёл, что граф строился задом наперёд, а псевдоверсии Go превращали любую версию в уязвимую. Рассказываю, как это нашлось и как проверить, что исправление действительно исправление.

Читать дальше

Машинное обучение головного мозга

Уровень сложностиПростой
Время на прочтение25 мин
Охват и читатели9.2K

Дрессировочный ошейник для собак на предплечье, провод в COM‑порт ноутбука, португальская фраза в наушниках. Ошибусь на букве — ударит током.

Я занимаюсь машинным обучением, и однажды я задал вопрос, от которого преподавателя передёрнет: чем обучение человека принципиально отличается от обучения модели? А дальше два года проверял ответ на самом живом — на собственной голове.

Половина второго ночи. На левом предплечье у меня застёгнут дрессировочный ошейник для собак — тот самый, с металлическими контактами. От него тянется провод к COM‑порту старого ноутбука. На экране — португальская фраза, я слышу её в наушниках и должен набрать вслепую. Палец висит над клавишей. Я знаю: ошибусь на букве — меня ударит током. Не сильно. Достаточно.

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

И сразу оговорюсь, чтобы ошейник не выглядел аттракционом ради красивого начала: без этой дури не было бы всего остального. Именно он показал мне, почему сигнал вообще перестаёт работать, — а из этого выросло всё, что сегодня действительно держит и меня, и семью за столом. Так что мы к нему ещё вернёмся, и не один раз.

Читать далее
1
23 ...