cpluspluc | Unsorted

Telegram-канал cpluspluc - C++ Academy

16151

По всем вопросам- @haarrp @itchannels_telegram - 🔥 best it channels РКН: clck.ru/3FmxJF

Subscribe to a channel

C++ Academy

Лето, ИТ-Пикник и музыка известных артистов уже через несколько дней!

8 августа в Коломенском пройдет ИТ-Пикник.

В программе — выступления проекта LAB Антона Беляева, IOWA, Cream Soda, Pompeya, мартина и Совы.

А днем — научпоп-лекции, дискуссии об ИИ и больших языковых моделях, мастер-классы и интерактивы. Полезные знакомства и развлечения тоже будут.

Зарегистрироваться и узнать подробности можно на сайте мероприятия.

В билет входит +1 — можно позвать близких и друзей.

До встречи в месте притяжения ИТ.

Читать полностью…

C++ Academy

Оператор # в препроцессоре C превращает токены в строковые литералы ещё на этапе компиляции.

Никакого преобразования во время выполнения не происходит.

Ядро Linux использует этот трюк в макросах вроде WARN_ON(), чтобы вывести точное условие, которое не прошло проверку.

Вы пишете выражение один раз, а препроцессор автоматически генерирует соответствующую строку.

Один оператор - и ваши debug-сообщения остаются идеально синхронизированы с кодом.

Читать полностью…

C++ Academy

C++ enum class: безопасно, но местами раздражает

enum class даёт строгую типизацию и не позволяет случайно смешивать значения с обычными числами.

Но есть нюанс: даже если enum используется как набор флагов,


Flags::Read | Flags::Write


не скомпилируется.

Для |, &, ^, ~ придётся вручную определить операторы и приводить значения к базовому типу.

Это правильное поведение с точки зрения type safety, но бойлерплейта становится заметно больше.

Поэтому в некоторых C++-проектах для битовых флагов до сих пор используют обычный enum внутри namespace: меньше защиты, зато код значительно проще.

Читать полностью…

C++ Academy

🔥 Как найти младший установленный бит без цикла

Этот трюк возвращает позицию самого правого бита 1 в 32-битном числе:


static const int table[32] = {
0, 1, 28, 2, 29, 14, 24, 3,
30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7,
26, 12, 18, 6, 11, 5, 10, 9
};

int lowest_set_bit(uint32_t v)
{
return table[((v & -v) * 0x077CB531U) >> 27];
}


Выражение v & -v изолирует младший установленный бит.

Затем результат умножается на константу 0x077CB531 из последовательности де Брёйна. Для каждой из 32 возможных позиций старшие 5 бит произведения образуют уникальный индекс.

Остаётся одно обращение к таблице - и позиция найдена без перебора всех битов.

Важно: функция рассчитана на v != 0.

В современном коде также стоит проверить std::countr_zero() или __builtin_ctz() - компилятор часто превращает их в одну инструкцию процессора.

Читать полностью…

C++ Academy

🌍🚀 Pointerverse: Версионный контроль для ветвящихся миров

Pointerverse — это детерминированный движок для создания проверяемых миров. Вы описываете мир как программу, создаете контент-адресованные коммиты и проверяете каждое изменение по заданным законам. Это позволяет воспроизводить историю и анализировать последствия изменений.

🚀Основные моменты:
- Детерминированное управление историей с проверкой на соответствие законам.
- Возможность ветвления и сравнения различных сценариев.
- Полная воспроизводимость и защита от подделок с помощью Merkle DAG.
- Поддержка написания собственных миров с использованием языка .pv.

📌 GitHub: https://github.com/farukalpay/Pointerverse

Читать полностью…

C++ Academy

Даже формально верифицированный компилятор может ошибаться

В 2011 году исследователи тестировали CompCert случайно сгенерированными C-программами и нашли wrong-code баг в таком выражении:

return -1 <= (1 && x);

Правильный результат — 1, но CompCert 1.6 для PowerPC возвращал 0.

Ошибка оказалась не в доказанно корректном оптимизаторе, а в неверифицированном фронтенде.

Формальная верификация защищает только те части системы, для которых действительно построено доказательство.

Читать полностью…

C++ Academy

От инженеров для инженеров: 1 августа в Москве, Белграде и Ереване пройдет бэкенд-конференция Яндекса — Back to Back

Старый добрый C++ Zero Cost Conf расширил формат и добавил новые бэкенд-направления — от низкоуровневой эффективности и производительности до архитектуры и надёжности продакшен-систем. Всего доступно два трека: C++ Zero Cost (Москва/Белград) и Architecture & Performance (Москва/Ереван).

— В Москве Антон Полухин, руководитель РГ21 C++, обсудит главные новости со встречи Международного комитета по стандартизации C++, ответит на вопросы о развитии C++26 и планах на C++29.

— Там же Константин Владимиров и Елизавета Носкова из Syntacore, разберут, что C++ программист должен знать про ABI. А Антон Пионтковский, разработчик YDB, расскажет, как мы считаем range-предикаты с помощью битовых масок и как комбинировать их между колонками.

Три города — три программы: Москва, Белград и Ереван.

Если планируете посетить конференцию в Москве, вас ждут экспертные сессии 1:1 с разбором карьерных запросов и выступление группы «Научно-технический рэп».

Конференции во всех городах пройдут и офлайн, и онлайн.

Зарегистрироваться можно здесь.

Читать полностью…

C++ Academy

🤖 RSA почти никогда не делит числа по модулю напрямую

Операции с огромными числами слишком дорогие, поэтому реализации RSA используют редукцию Монтгомери.

Идея Питера Монтгомери из 1985 года:

выбирается R = 2^k
деление на R заменяется битовым сдвигом
модульные вычисления выполняются через умножения, сложения и сдвиги

За счёт этого быстрее считается:

a^e mod N

Это критично для:

шифрования и расшифровки
цифровых подписей
TLS-соединений
банковских операций

Редукция Монтгомери десятилетиями работает внутри криптографических библиотек, хотя большинство пользователей даже не знает о её существовании.

Читать полностью…

C++ Academy

Cuckoo hashing даёт O(1) lookup в худшем случае

Не амортизированно.

Не «в среднем».

А именно worst case.

Идея красивая: у каждого ключа есть ровно две возможные позиции в таблице.

Поэтому поиск тупо проверяет оба места и заканчивается.


return table1[h1(key)] == key
|| table2[h2(key)] == key;


Вставка работает интереснее: если место занято, новый ключ «выталкивает» старый в его альтернативную позицию.

Отсюда и название: как кукушка, которая выкидывает чужие яйца из гнезда.

Если начинается цикл, таблицу перестраивают с новыми хеш-функциями.

Алгоритм предложили Rasmus Pagh и Flemming Rodler в 2001 году.

И это не просто академическая штука: Linux kernel использует cuckoo hashing в connection tracking table.

Один из тех случаев, когда простая идея даёт очень сильную гарантию по lookup.

Читать полностью…

C++ Academy

C++23 добавил `std::expected`, и это одна из самых практичных вещей в языке за последние годы.

Идея простая: функция возвращает либо нормальный результат, либо ошибку. Без исключений, без output-параметров и без неявного control flow, который потом сложно отследить.

Например, парсер заголовка может вернуть uint32_t, если всё хорошо, или std::error_code, если буфер слишком короткий. Вызывающая сторона сразу видит: здесь результат может быть ошибкой, её нельзя «случайно забыть» так же легко, как при старом стиле с кодами возврата.

Это особенно удобно для системного кода, сетевых протоколов, парсеров, embedded и всего, где исключения либо запрещены, либо нежелательны.

std::expected не делает обработку ошибок магической. Он просто заставляет контракт функции быть честным: успешный результат и возможная ошибка описаны прямо в типе.

Читать полностью…

C++ Academy

⚡️ Почему обычный `min(a, b)` в C может вернуть неожиданный результат

В C есть неприятная ловушка: если сравнивать signed и unsigned значения, компилятор может привести оба числа к unsigned.

И тогда отрицательное число внезапно превращается в огромное положительное.

Пример:


#define min(a, b) ((a) < (b) ? (a) : (b))

int x = -1;
unsigned int y = 10;

printf("%u\n", min(x, y));


Интуитивно кажется, что минимум — -1.

Но при сравнении x < y значение -1 приводится к unsigned и становится очень большим числом. В итоге сравнение работает уже не так, как ожидает разработчик.

Именно поэтому в Linux kernel макрос min() устроен хитрее. Он не просто сравнивает два значения, а сначала делает type check:


#define min(x, y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; \
})


Ключевая строка здесь:


(void) (&_x == &_y);


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

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

В низкоуровневом коде такие мелочи решают очень много. Один неудачный implicit conversion — и проверка размера, индекса или лимита начинает работать против вас.

Читать полностью…

C++ Academy

Один из самых дорогих багов в истории Debian начался с «невинной» правки.

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

Статические анализаторы и Valgrind ругались на это как на ошибку.

Мейнтейнер решил убрать предупреждение и удалил две строки.

На вид - чистка мусора.

По факту - генератор случайных чисел потерял важный источник энтропии.

И почти два года Debian OpenSSL выпускал предсказуемые ключи.

Пострадали SSL-сертификаты, SSH-ключи, VPN, серверы и всё, что зависело от нормальной криптографической случайности.

Урок жёсткий: в security-коде странная строка не всегда мусор.

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

Читать полностью…

C++ Academy

🚀 SIMD-ускоренное преобразование целых чисел в строки

Simditoa - библиотека для быстрого преобразования 64-битных целых чисел в десятичные строки с использованием SIMD-инструкций. Достигает скорости менее 2 наносекунд на современном оборудовании, обеспечивая высокую производительность на архитектурах x86-64.

🚀 Основные моменты:
- Поддержка AVX-512 для максимальной скорости.
- Альтернативная скалярная реализация для совместимости.
- Простой API для интеграции в проекты C++.
- Значительное ускорение по сравнению с std::to_chars.

📌 GitHub: https://github.com/simditoa/simditoa

#cpp

Читать полностью…

C++ Academy

volatile в C нужен не «для красоты», а чтобы компилятор не сломал работу с железом.

Когда код читает memory-mapped IO регистр, значение может измениться не из-за программы, а из-за устройства.

Например:


#define STATUS_REG (*(volatile uint32_t*)0x40000000)
#define READY_BIT (1 << 0)

while (!(STATUS_REG & READY_BIT)) {
// ждём, пока железо станет ready
}


Без volatile компилятор может решить:

«Значение не меняется внутри цикла, значит можно прочитать один раз».

И всё. Опрос регистра превращается в бесконечный цикл или вообще оптимизируется не так, как вы ожидали.

Главная мысль:

volatile говорит компилятору:
это значение может измениться вне твоего контроля, не трогай чтения и записи.

Важно: volatile не заменяет mutex, atomics и memory barriers. Но для MMIO-регистров это база, без которой embedded-код может вести себя как магия из ада.

Читать полностью…

C++ Academy

🎯 Продвинутое использование отладчика GDB

Приглашаем на открытый урок.

🗓 08 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Системное программирование».

Программа урока:
✔️Кратко вспомним базовое использование GDB;
✔️Написание сценариев GDB;
✔️Условные точки останова и точки наблюдения;
✔️Дампы памяти и отладка по сети.

После занятия вы будете знать:
• Как отлаживать программы на другой машине;
• Как использовать возможности автоматизации отладчика для поимки плавающих багов;
• Как отладчик работает "под капотом".;

🔗 Ссылка на регистрацию: https://otus.pw/vKKX/?erid=2W5zFJLXK5K


Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

Читать полностью…

C++ Academy

Четыре строки делают сложение `float` заметно точнее

При последовательном сложении чисел с плавающей точкой часть младших битов теряется из-за округления. На больших массивах эта ошибка постепенно накапливается.

Алгоритм Кэхэна хранит потерянную часть в отдельной переменной и компенсирует её на следующем шаге:


float kahanSum(const float *nums, int count)
{
float sum = 0.0f;
float correction = 0.0f;

for (int i = 0; i < count; ++i)
{
float adjusted = nums[i] - correction;
float next = sum + adjusted;

correction = (next - sum) - adjusted;
sum = next;
}

return sum;
}


Здесь correction запоминает ошибку округления, которая потерялась при предыдущем сложении.

Обычная сумма быстрее, но Kahan Summation полезен там, где важна численная точность:

- научные расчёты;
- статистика и аналитика;
- графика и симуляции;
- обработка больших массивов;
- накопление очень маленьких значений рядом с большими.

Метод предложил Уильям Кэхэн в 1965 году. Небольшое усложнение цикла может заметно уменьшить ошибку без перехода на более тяжёлый числовой тип.

Читать полностью…

C++ Academy

LEA в x86 выглядит как инструкция для адресов, но компиляторы часто используют её как скрытый калькулятор.

Формально LEA считает адрес без обращения к памяти:


lea eax, [rdi + 3]


Но по факту это обычная арифметика:


return x + 3;


Ещё хитрее:


lea eax, [rdi + rdi*4]


Это уже:


return x * 5;


Почему так делают?

Потому что x86-адресация умеет base + index * scale + offset, а LEA позволяет использовать эту механику без чтения памяти.

Бонус: LEA не трогает флаги процессора, в отличие от add.

Красота C и asm в том, что за простой строкой x * 5 может стоять не mul, а маленький трюк архитектуры.

Читать полностью…

C++ Academy

Doom в 1993 работал на 486 и 4 МБ RAM. А современные игры почему едят 16 ГБ?

Секрет был в BSP-дереве: уровень заранее делился на области, а движок во время рендера просто обходил дерево в нужном порядке. Без z-buffer, без лишней магии, без пересчёта видимости с нуля каждый кадр.

Кармак буквально заставил геометрию работать вместо железа.

Подписывайся, тут ещё много таких историй про код, который унижает современные «оптимизации».

Читать полностью…

C++ Academy

🛠️ Cup: C-Based Build System

Cup — это система сборки, написанная на C, позволяющая использовать C в качестве языка сценариев. Она поддерживает сложную логику сборки и интеграцию с инструментами разработки, такими как LSP и отладчики.

🚀Основные моменты:
- Полная поддержка C без использования DSL.
- Автоматическое обновление и кэширование сборок.
- Поддержка Windows, Linux и macOS.
- Генерация файлов конфигурации для популярных IDE.
- Легковесные сборки и параллельные команды.

📌 GitHub: https://github.com/howaajin/cup

#c

Читать полностью…

C++ Academy

✔️ std::exchange: правильный move-конструктор без double free

Move-конструктор через ручное копирование полей это ловушка. Скопировал указатель, забыл занулить источник, и оба объекта в деструкторе зовут delete по одному адресу. Double free: иногда падает сразу, иногда через неделю в проде.

std::exchange закрывает вопрос одним вызовом. Он забирает ресурс и кладёт в источник безопасное значение:


Handle(Handle&& other)
: ptr(std::exchange(other.ptr, nullptr)) {}


Новый объект получает старый указатель, а в other.ptr уезжает nullptr. delete по nullptr это no-op, поэтому перемещённый объект уничтожается безопасно, и владелец у ресурса ровно один.

Именно так пишет стандартная библиотека внутри. Коротко, exception-safe, без шанса забыть про зануление. Одна функция против двух строк, на которых легко ошибиться.

Правило короткое: перемещаешь владеющий указатель, бери std::exchange.

Читать полностью…

C++ Academy

⚡️ C++26: прямой доступ к типу внутри parameter pack

В C++26 появился pack indexing. Теперь тип по индексу можно получить напрямую из набора параметров:


template<std::size_t I, typename... Ts>
using nth_t = Ts...[I];

using Second = nth_t<1, int, double, std::string>;
// Second = double


Индексация начинается с нуля.

Раньше для этого использовали std::tuple_element_t, вспомогательные шаблоны или рекурсию:


template<std::size_t I, typename... Ts>
using old_nth_t = std::tuple_element_t<I, std::tuple<Ts...>>;


Новый синтаксис короче и понятнее:


Ts...[I]


Пригодится в шаблонных библиотеках, метапрограммировании, traits и compile-time API.

Читать полностью…

C++ Academy

✔️ Furtex: исследовательский набор для Linux post-exploitation и обхода EDR

В open source вышел Furtex - низкоуровневый toolkit для изучения техник post-exploitation и evasion в Linux.

Проект построен вокруг io_uring, BPF и eBPF. Автор намеренно отказался от liburing и готовых фреймворков: взаимодействие с ядром реализовано через raw syscalls.

В репозитории собраны эксперименты для:

- анализа возможностей io_uring
- исследования BPF-карт и программ
- тестирования Linux EDR
- изучения видимости событий для средств мониторинга
- проверки защитных правил Falco
- исследования сетевых и процессных механизмов ядра

Furtex интересен специалистам по Linux security, разработчикам EDR и red team-инженерам, которым важно понимать, какие действия могут проходить мимо привычных точек наблюдения.

Автор отдельно подчёркивает: проект предназначен только для разрешённых исследований и тестирования собственной инфраструктуры.

https://github.com/MatheuZSecurity/Furtex

#linux #cybersecurity #ebpf #io_uring #research

Читать полностью…

C++ Academy

🔥 Хочешь быстрее расти в IT? Хватит учиться в одиночку

В IT прокачивается тот, кто каждый день видит сильные идеи, новые инструменты, реальные задачи, вакансии и разборы.

Окружение решает больше, чем кажется.

Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.

AI: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Хакинг: t.me/linuxkalii
DevOps: t.me/DevOPSitsec
Docker: t.me/DevopsDocker
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_1001_notes
Java: t.me/java_library
JavaScript: t.me/javascriptv
React: t.me/react_tg
Frontend: t.me/front
PHP: t.me/phpshka
Android: t.me/android_its
Мобильная разработка: t.me/mobdevelop
Базы данных: t.me/sqlhub
Data Science: t.me/data_analysis_ml
Big Data: t.me/bigdatai
Математика: t.me/data_math
Физика: t.me/fizmat
Kubernetes: t.me/kubernetc
GameDev: /channel/gamedev
Haskell: t.me/haskell_tg

Собеседования и карьера:

DS собеседования: t.me/machinelearning_interview
Python собеседования: t.me/python_job_interview

Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: /channel/addlist/2Ls-snqEeytkMDgy
Папка Frontend: /channel/addlist/mzMMG3RPZhY2M2Iy

Полезное сверху:

ИТ-мемы: t.me/memes_prog
Английский для программистов: t.me/english_forprogrammers
ИИ и технологии: t.me/vistehno
954 ГБ open-source курсов: @courses
ИТ-книги бесплатно: /channel/addlist/BkskQciUW_FhNjEy

Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg

Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.

Пока кто-то листает шум, ты будешь видеть инструменты, задачи и идеи, которые помогают расти в профессии.

Читать полностью…

C++ Academy

⁉️ malloc — кто же ты на самом деле?

Приглашаем на открытый урок.

🗓 23 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Системное программирование».

Программа урока:
✔️ Как работает malloc и какую роль он играет в управлении памятью в системном программировании;
✔️ Что происходит при выделении памяти: от вызова функции до взаимодействия с ОС и аллокатором;
✔️ Какие типичные ошибки возникают при работе с динамической памятью и к каким последствиям они приводят;
✔️ Как понимать поведение программ на уровне памяти и писать более надежный и предсказуемый код.

После занятия вы будете знать:
• Как устроено динамическое выделение памяти в программах на низком уровне;
• Что именно делает malloc и почему его работа не сводится к "просто выделить память";
• Как более осознанно использовать механизмы управления памятью в системной разработке.

🔗 Ссылка на регистрацию: https://otus.pw/qQjk/?erid=2W5zFG1oCNd


Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

Читать полностью…

C++ Academy

🚀 Anthropic выложили reference harness для поиска и исправления уязвимостей с Claude

Очень недооценённый репозиторий для defensive security.

Идея простая: Claude проходит полный цикл работы с уязвимостью:

* threat model
* поиск подозрительных мест
* проверка
* triage
* отчёт
* патч

Внутри есть Claude Code skills вроде /vuln-scan, /triage и /patch, которые можно запускать интерактивно.

Есть и автономный harness: можно настроить цель, ограничения и дать агенту самому пройти цикл анализа.

https://github.com/anthropics/defending-code-reference-harness

Читать полностью…

C++ Academy

C умел «объектный стиль» задолго до модных споров про ООП.

В Linux-драйверах это видно особенно хорошо. Каждый драйвер фактически реализует интерфейс, просто заполняя структуру с указателями на функции.

file_operations из include/linux/fs.h - хороший пример. Ядро говорит: вот набор операций, которые может поддерживать файл, сокет или устройство. Драйвер сам решает, какие обработчики дать:

open
read
write
release
mmap
fsync
unlocked_ioctl

Если операция не нужна, поле остаётся NULL, и ядро использует поведение по умолчанию там, где это возможно.

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

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

Просто вместо красивого слова interface у тебя struct с function pointers.

#programming #linux #c

Читать полностью…

C++ Academy

Красота C в том, что он почти не прячет механику компьютера.

Хочешь понять, как копируется файл? Не нужен огромный фреймворк. Достаточно посмотреть на простой C-код:

• открыть исходный файл через fopen

• открыть файл назначения

• выделить буфер через malloc

• читать кусками через fread

• записывать через fwrite

• освободить память и закрыть файлы

Всё честно и прямо: байты читаются из одного места и записываются в другое.

Именно поэтому C до сих пор так важен. Он не всегда самый удобный, но он показывает, что реально происходит под капотом.

После такого начинаешь лучше понимать не только язык, а саму систему.

Читать полностью…

C++ Academy

Godot фактически запрещает vibe coding в контрибуциях.

Причина простая: PR стало легче генерировать, но не легче проверять. Для open-source движка каждый патч всё равно должен разобрать мейнтейнер, который понимает архитектуру, риски и последствия изменений.

Теперь автономные агенты, крупные AI-сгенерированные куски кода и сгенерированный текст в issues, proposals и PR-дискуссиях запрещены. Разрешены только мелкие помощники вроде автодополнения, regex и find/replace. Помощь AI в коде нужно раскрывать.

На практике правило будет сложно применять: почти невозможно наверняка доказать, где был vibe coding, а где обычная работа разработчика.

Godot защищает не стиль разработки, а время ревьюеров. Код можно сгенерировать за минуты, но ответственность за него всё равно остаётся на людях.

godotengine.org/article/contribution-policy-2026/

Читать полностью…

C++ Academy

⚡️ Почему RSA в OpenSSL не делает «обычное деление»

В реализации RSA внутри OpenSSL почти не используется прямое модульное деление. Вместо этого там работает Montgomery reduction - алгоритм, который ещё в 1985 году предложил Питер Монтгомери.

Идея простая: в RSA постоянно нужны операции вида «умножили большие числа и взяли остаток по модулю». Обычное деление на больших числах дорогое, поэтому его стараются избегать.

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

Для пользователя это незаметная деталь. Но без таких трюков современный RSA был бы намного медленнее.

Есть хороший шанс, что HTTPS-соединение, которым вы пользуетесь прямо сейчас, где-то внутри уже опиралось на эту технику.

Читать полностью…

C++ Academy

В C++20 у std::atomic появились wait() и notify_one().

Это удобная штука для случаев, когда поток должен просто дождаться изменения атомарного значения без mutex, condition_variable и ручного busy waiting.

Раньше для такого обычно оборачивали OS-level примитивы вроде futex или pthread_cond.

Теперь можно писать прямо так:


#include <atomic>
#include <thread>

std::atomic<bool> ready{false};

void waiter() {
ready.wait(false, std::memory_order_acquire);
}

void notifier() {
ready.store(true, std::memory_order_release);
ready.notify_one();
}


Что здесь происходит:

wait(false) блокирует поток, пока ready остаётся false.

Другой поток делает store(true) и будит ожидающего через notify_one().

Главное отличие от обычного цикла проверки - поток не крутится впустую и не жрёт CPU.

Это не полная замена condition_variable.

Для сложных predicates, очередей и нескольких условий condition_variable всё ещё нужен.

Но для простого флага, состояния или lightweight-синхронизации std::atomic::wait часто даёт более чистый и быстрый код.

C++20 тихо добавил одну из самых полезных низкоуровневых фич для concurrent programming.

Читать полностью…
Subscribe to a channel