#HEX • IT – Telegram
#HEX • IT
428 subscribers
510 photos
104 videos
64 files
492 links
Channel by @alexeev_dev.

Авторский блог.

IT, статьи и другая информация.
Download Telegram
#HEX • IT pinned «Каждый, кто проводит в терминале больше пяти минут, сталкивается с одним и тем же: одни и те же длинные команды приходится набирать снова и снова, а рутинные действия отнимают время и внимание. Сначала терпишь, потом — начинаешь оптимизировать. Простейший…»
Всем привет! Небольшой отход от основной темы канала, я решил попробовать себя в перевод и перевел статью "Raspberry Pi Drag Race: Pi 1 to Pi 5 – Performance Comparison" с Hacker News.

Сегодня мы хотим рассмотреть на практике 13 летнюю историю разработки Raspberry Pi. У меня есть экземпляры каждого поколения Pi, от оригинальной модели из 2012 года, до Pi 5, которая вышла чуть больше года назад.

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

Читать статью - https://habr.com/ru/articles/988770/

Буду рад фидбеку по качеству перевода и по заинтересованности в теме КПК.
2👍2🔥2
Индексы в PostgreSQL — это специальные структуры данных, которые ускоряют поиск информации в таблицах, но требуют определённых затрат. Работают они, грубо говоря, как указатель в книге: вместо того чтобы листать все страницы (читать всю таблицу с диска), система быстро находит нужные строки по специальной карте — индексу.

Когда вы создаёте индекс, PostgreSQL строит по выбранному столбцу упорядоченную структуру (чаще всего B-дерево), которая связывает значение в столбце с физическим адресом строки в таблице. Это позволяет находить данные за логарифмическое время, даже в огромных таблицах. Например, поиск одного игрока в таблице из миллиона строк без индекса заставляет систему прочитать все строки (последовательное сканирование), что занимает сотни миллисекунд. С индексом — только несколько страниц и доли миллисекунд.

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

PostgreSQL предлагает несколько типов индексов под разные задачи. B-tree — самый универсальный и часто используемый, подходит для сравнений и сортировок. Hash — компактный и быстрый для точного совпадения, но не для диапазонов. BRIN — очень компактный, идеален для больших упорядоченных данных (например, временных рядов), где значения коррелируют с их расположением на диске. GIN — специализируется на поиске внутри составных данных: текста, массивов, JSON. GiST и SP-GiST — это, скорее, frameworks для создания индексов под сложные типы данных, вроде геометрических объектов или полнотекстового поиска.

Важно помнить, что индекс помогает только если запрос обращается к проиндексированным столбцам, и если выбирается небольшая доля строк (обычно до 15-20%). Иначе планировщик может проигнорировать индекс и просканировать таблицу целиком. Также есть продвинутые техники: частичные индексы (индексирующие только часть строк по условию), многоколонные индексы (порядок столбцов в них критичен) и покрывающие индексы (которые содержат все данные для запроса, избавляя от обращений к таблице).

Читать подробнее оригинал на английском
2🔥5👍321
Алгоритм XOR Swap

Классический алгоритм, который позволяет обменивать значения двух переменных с помощью трёх операций XOR без создания временной третьей.

void xor_swap(int *a, int *b) {
if (a != b) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
}


Классический, но всегда впечатляющий новичков трюк: обмен значений двух переменных с помощью трёх операций XOR. Это демонстрирует симметрию и свойства операции XOR. Хотя на современных процессорах это часто медленнее, чем использование временной переменной (из-за параллелизма), трюк остаётся красивым и поучительным.

Первая операция сохраняет разность a и b в a, вторая, используя исходное b и новое a, получает исходное a и сохраняет в b, и последняя, используя новое a и новое b, получает исходное b и сохраняет в a.
👍63🔥31
Алгоритм Ричардса (Richards’ Curve) — это метод оценки параметров нелинейной кривой роста (generalized logistic curve). Модель была предложена британским биологом Ф. Дж. Ричардсом в 1959 году. Она показывает тенденцию количественного роста: в начале она небольшая (стадия бурного роста), затем быстро увеличивается (стадия быстрого роста) и, наконец, стабилизируется в диапазоне значений (стадия насыщения).

Давайте реализуем быструю версию этого алгоритма:

float fast_sin(float x) {
const float a = 4.0f / (M_PI * M_PI);
const float p = 0.225f;
x = a * x * (M_PI - fabs(x));
return p * (x * fabs(x) - x) + x;
}


Идея в том, чтобы быстро вычислять синус на ограниченном интервале (от –π до π), используя только умножения, сложение и fabs. Это важно для эмбеддед систем, где нельзя использовать или нет доступа к стандартным методам.

Сначала он делает базовую параболическую волну: x = a * x * (π - |x|). Эта простая формула уже похожа на синус. Затем идёт коррекция погрешности через полином третьей степени: p * (x * |x| - x) + x. Это эквивалентно x + p*x³ - p*x. Коэффициент p=0.225 подобран, чтобы финальная кривая максимально близко легла на настоящий синус, используя минимум вычислений. Всё сводится к нескольким умножениям и сложениям.
👍832🌭1
Алгоритм bitboard для шахмат/игр

Использование 64-битных чисел для игрового поля — классика оптимизации.

#include <stdio.h>
#include <stdint.h>

typedef uint64_t Bitboard;

Bitboard knights_attacks(Bitboard knights) {
Bitboard l1 = (knights >> 1) & 0x7F7F7F7F7F7F7F7F;
Bitboard l2 = (knights >> 2) & 0x3F3F3F3F3F3F3F3F;
Bitboard r1 = (knights << 1) & 0xFEFEFEFEFEFEFEFE;
Bitboard r2 = (knights << 2) & 0xFCFCFCFCFCFCFCFC;
return (l1 | r1) << 16 | (l1 | r1) >> 16 | (l2 | r2) << 8 | (l2 | r2) >> 8;
}

void print_bitboard(Bitboard bb) {
for (int row = 7; row >= 0; row--) {
for (int col = 0; col < 8; col++) {3
int square = row * 8 + col;
printf("%c ", (bb >> square) & 1 ? '1' : '.');
}
printf("\n");
}
printf("\n");
}

int main() {
Bitboard knight = 1ULL << 36; /* конь на e4*/

printf("позиция коня:\n");
print_bitboard(knight);

printf("возможные ходы коня:\n");
Bitboard attacks = knights_attacks(knight);
print_bitboard(attacks);

return 0;
}


⚡️Фанфакт: в английском как шахматная фигура конь это не horse, а knight. Ладья - Rook (грач/утес/башня). Слон - Bishop (епископ).


Функция knights_attacks вычисляет все возможные ходы коня за несколько битовых операций. Принцип такой: конь ходит буквой "Г" — на две клетки в одном направлении и одну в перпендикулярном.

Алгоритм делает сдвиги в четыре стороны. Сначала сдвигает позиции коней влево и вправо на 1 и 2 клетки (l1, r1, l2, r2). Маски 0x7F... и 0xFE... нужны чтобы не было "перетекания" битов через края доски — они отсекают боковые столбцы.

Затем комбинируем эти сдвиги. Объединение l1 и r1 дает горизонтальные смещения на одну клетку. Сдвиг этой комбинации на 16 рядов вверх и вниз дает вертикальное смещение на две клетки — получаем ходы типа "две вверх/вниз, одна вбок". Аналогично l2 и r2 дают смещение на две клетки по горизонтали. Сдвиг на 8 рядов дает смещение на одну клетку по вертикали — это ходы "одна вверх/вниз, две вбок".

Битовое ИЛИ всех четырех вариантов дает полную маску атак.

Главная прелесть — всего 10 битовых операций для любого количества коней на доске. Вместо перебора 64 клеток или циклов по фигурам — мгновенный расчет. Именно так работают современные шахматные движки.

При запуске мы получаем такой красивый вывод:

позиция коня:
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . 1 . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .

возможные ходы коня:
. . . . . . . .
. . . 1 . 1 . .
. . 1 . . . 1 .
. . . . . . . .
. . 1 . . . 1 .
. . . 1 . 1 . .
. . . . . . . .
. . . . . . . .
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍74🔥41
Доброго времени суток, господа и дамы! Иногда у некоторых людей возникает желание заняться откровенным непотребством в программировании — то, что не несет практической пользы напрямую, но помогает развлечься. И я — не исключение. В этой статье я хочу рассказать вам о лайфхаках, трюках (магических и не очень) и алгоритмах на языке C!

Идея написать эту статью зародилась из моего поста, после него я начал серию статей, которая раскрывала много интересных моментов — от математических алгоритмов и оптимизации до ГПСЧ.

Если вы видите на экране эту часть нашей бесконечной саги о ненормальном программировании на C, значит, мы с вами прошли уже немало: от конвертации миль в километры через Фибоначчи до ГПСЧ и быстрых вычислений.

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

https://habr.com/ru/companies/timeweb/articles/986348/
73🔥31
#HEX • IT pinned «Доброго времени суток, господа и дамы! Иногда у некоторых людей возникает желание заняться откровенным непотребством в программировании — то, что не несет практической пользы напрямую, но помогает развлечься. И я — не исключение. В этой статье я хочу рассказать…»
Прямой доступ к битам дробного числа

В языке C нет прямого способа посмотреть битовое представление числа с плавающей запятой. Трюк в том, чтобы заставить память интерпретироваться по-разному. Для этого используется union — область памяти, в которой данные разных типов хранятся по одному и тому же адресу.

#include <stdio.h>
#include <stdint.h>

typedef union {
float f;
struct {
uint32_t mantissa : 23;
uint32_t exponent : 8;
uint32_t sign : 1;
} bits;
} float_cast;

int main() {
float_cast fc;
fc.f = -3.14f;

printf("Number: %f\n", fc.f);
printf("Sign: %u\n", fc.bits.sign);
printf("Exponent: %u\n", fc.bits.exponent);
printf("Mantissa: 0x%06X\n", fc.bits.mantissa);
return 0;
}


Объявляется union с именем float_cast. Внутри него два поля: обычное число float f и структура bits. Они занимают один и тот же участок памяти размером 4 байта (32 бита). Когда мы записываем значение в fc.f, биты сразу располагаются в соответствии со стандартом IEEE 754. Через структуру bits мы получаем доступ к этим же битам, но уже как к отдельным именованным полям: знак (1 бит), порядок (8 бит) и мантисса (23 бита). Это не создаёт копии и не конвертирует данные — это просто другая «маска» для просмотра тех же битов.

IEEE 754 (IEC 60559) — стандарт IEEE, описывающий формат представления чисел с плавающей точкой. Разработан в 1985 году группой инженеров, озабоченных проблемой несовместимости представления чисел с плавающей точкой в различных компьютерных системах.


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

Number: -3.140000
Sign: 1
Exponent: 128
Mantissa: 0x48F5C3
7👍531🔥1
#HEX • IT
Доброго времени суток, господа и дамы! Иногда у некоторых людей возникает желание заняться откровенным непотребством в программировании — то, что не несет практической пользы напрямую, но помогает развлечься. И я — не исключение. В этой статье я хочу рассказать…
Буду рад плюсикам на хабре, на следующих неделях планируется публикация еще 2 статей на тему трюков в си.

А также пишутся статьи про реализацию ГПСЧ на C, звуковые сервисы в Linux, обзор-гайд на новый фреймворк Django-Modern-Rest, и перевод статьи про type pinning в C++
👍42🔥1
Как обнаружить SSH-туннель на сервере, если сетевой трафик зашифрован?

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

Самый надежный способ — не смотреть трафик (он ведь в SSH зашит), а смотреть на поведение процесса sshd на уровне ядра. В этом нам помогает auditd (Linux Audit Daemon).

SSH-демон при создании туннеля совершает два ключевых системных вызова, которые видны в логах аудита:

⚪️ bind() — Когда процесс открывает порт для прослушивания (характерно для удаленных туннелей).

⚪️ connect() — Когда процесс инициирует подключение к другому хосту (характерно для локальных туннелей).

Правила auditd должны ловить эти вызовы только для сетевых соединений (IPv4/IPv6), чтобы не захламлять логи подключениями к локальным сокетам.

🔴 a2=0x10 — фильтр для IPv4.

🔴 a2=0x1C — фильтр для IPv6.

‼️ Главный триггер для Sigma Rule и KUMA Rule: Мы ищем вызовы connect или bind от процесса sshd, у которого в командной строке (procnoscript) есть строка "sshd". Так мы отсекаем обычный логин и видим именно попытку туннелирования.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥431
Что происходит в опенсорсе прямо сейчас: Rust, ИИ и денежные потоки

2026 год только начался, а уже был наплыв новостей, чуть ли не переворачивающих стереотипы об open source. За последнее время случилось столько, что хоть стой, хоть падай.

🤩 Anthropic готовится к IPO
Компания собирается первой монетизировать ИИ по-крупному. Публичная демонстрация C-компилятора от Claude Code (который, к слову, провалил независимые тесты) — лишь вершина айсберга. Главная новость: Anthropic поглотила Bun.js — популярный скоростной рантайм для JavaScript. Стартап привлек $700 млн загрузок в месяц и семь сотрудников, которые теперь переходят к новому владельцу. Проект останется open source, но суть ясна: AI-гиганты скупают инфраструктуру, чтобы не зависеть от сторонних разработчиков. Оценка Anthropic уже подскочила до $300–350 млрд.

⚫️ Rust в мейнстриме
Язык продолжает шествие по ключевым проектам:

⚙️ В CPython вводят Rust, и согласно опубликованному Pre-PEP'у, он заходит по графику:

3.15 — сборщик начнет предупреждать об отсутствии Rust
3.16 — отключить Rust можно будет только флагом --with-rust=no
3.17 — Rust может стать обязательной зависимостью

Причины логичны: Rust ловит use-after-free и выход за границы буфера на этапе компиляции. Плюс он критически важен для free-threaded Python — версии без GIL, которая наконец научится использовать многоядерные процессоры по-настоящему. Сообщество раскололось, даже Гвидо ван Россум настроен скептически.

⚡️Ответный удар
Rust пытается зайти в Linux и Git — и немедленно получает отпор. Ведущий разработчик XLibre создал форк Git, из которого выпилил Rust. Причина: подготовка к выходу Git 3.0, где Rust планируют сделать обязательным. Автор не хочет, чтобы его система зависела от «ненадежного компилятора, который нельзя запустить без бинарника».

🟢 ИИ душит опенсорс
Ситуация принимает пугающие обороты. Проекты тонут в PR, полных нейрослопа. GitHub признал проблему и рассматривает радикальные меры вплоть до ограничений на отправку пулл-реквестов.

👩‍💻Создатель curl Дэниел Стенберг называет 2024–2025 годы кошмаром — он даже закрыл баг-баунти программу, чтобы убрать финансовый стимул для мусорных репортов.

Появился проект «OpenSlopware» — список репозиториев, загаженных AI-кодом. Автор получил такую травлю, что удалил и репозиторий, и аккаунт в соцсети. Но интернет помнит всё: список форкнули, он продолжает жить.

⚡️Кульминация: нейробот нахамил мейнтейнеру Matplotlib за отклоненный PR. Теперь AI слоп приходит с AI-слэпом.

👩‍💻 Грег Кроа-Хартман, мейнтейнер стабильной ветки Linux, получил премию Excellence in Open Source 2026. Да, тот самый, который в 2024-м подписал исключение 11 российских разработчиков из мейнтейнеров. Времена наступают интересные.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍53🔥21
Доброго времени суток, господа и дамы! Иногда у некоторых людей возникает желание заняться откровенным непотребством в программировании — то, что не несет практической пользы напрямую, но помогает развлечься. И я — не исключение. В этой статье я хочу рассказать вам о лайфхаках, трюках (магических и не очень) и алгоритмах на языке C!

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

Добро пожаловать в восьмую часть. Прошу под кат — там будет жарко, быстро и очень, очень интересно.

https://habr.com/ru/companies/timeweb/articles/990110/
https://habr.com/ru/companies/timeweb/articles/990110/
https://habr.com/ru/companies/timeweb/articles/990110/
1👍43🔥2
#HEX • IT pinned a photo
#HEX • IT
pinned a photo
Django-Modern-Rest - REST-фреймворк для Django с типизацией, асинхронностью и блекджеком!

https://github.com/wemake-services/django-modern-rest

DMR - это новый проект, еще один фрейморк для REST API для Django >=5.2. Но его отличия - это полная типизация (проверена с mypy, pyright и pyrefly в strict-режиме) и асинхронность

Он поддерживает msgspec, pydantic2, поддерживает асинхронный Django без всяких вызовов sync_to_async внутри

Поддерживает генерацию openapi 3.1, все существующие примитивы и пакеты Django.

По лучшим традициям - 100% покрытие тестами.

Без нейрослопа. И без эмодзи!

Установка:

pip install django-modern-rest



django-modern-rest[msgspec] - для поддержки msgspec
django-modern-rest[pydantic] - для поддержки Pydantic
django-modern-rest[jwt] - для поддежки pyjwt

Документация - https://django-modern-rest.rtfd.io/

А также сам проект открыт для новых контрибьютеров!
14👍2🔥1
XXTEA — крошечный блочный шифр

Компактный и эффективный шифр для эмбединга, осдева или прочих ваших странных потребностей. XXTEA шифрует массив 32-битных слов налету, используя ключ из 4 слов. Алгоритм выполняет несколько раундов, на каждом смешивая данные с ключом через XOR, сдвиги и сложение.

#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))

void xxtea_encrypt(uint32_t *v, int n, uint32_t const key[4]) {
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n < 1) return;
rounds = 6 + 52/n;
sum = 0;
z = v[n-1];
do {
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++) {
y = v[p+1];
z = v[p] += MX;
}
y = v[0];
z = v[n-1] += MX;
} while (--rounds);
}


Первое, что делает алгоритм — вычисляет число раундов. Формула 6 + 52/n гарантирует, что даже для больших массивов будет выполнено достаточное количество перемешиваний. Начинается цикл с обнулённой переменной sum.

В каждом раунде к sum прибавляется число DELTA. Затем определяется e — индекс для выбора слова ключа, основанный на текущей сумме.

Далее идёт сердце алгоритма — внутренний цикл по всем словам массива, кроме последнего. Для каждого слова вычисляется замысловатая функция MX. В ней через сдвиги, сложения и XOR перемешиваются соседние слова (y и z), текущая сумма и часть ключа. Результат этого микса прибавляется к текущему слову, что и является шифрованием.

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

void xxtea_decrypt(uint32_t *v, int n, uint32_t const key[4]) {
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n < 1) return;
rounds = 6 + 52/n;
sum = rounds * DELTA;
y = v[0];
do {
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--) {
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
} while (--rounds);
}


Ну и также покажу функцию для дешифровки, ключевое отличие в обратном порядке операций и направлении. Если шифрование идёт «вперёд», то дешифрование идёт «назад», отменяя каждый шаг. Начальное значение sum не ноль, а rounds * DELTA — полная сумма, которая накопилась бы к концу шифрования. Важно понимать, что порядок обновления переменных y и z в дешифровании обратный по отношению к шифрованию, чтобы гарантировать, что при вычислении MX используются те же значения, что и при шифровании.

Ну и на примере демонстрация работы:

int main() {
uint32_t data[] = {0x12345678, 0x9ABCDEF0};
uint32_t key[4] = {0xA1B2C3D4, 0x5E6F7A8B, 0x9C0D1E2F, 0x3A4B5C6D};

printf("Original: 0x%08X 0x%08X\n", data[0], data[1]);

xxtea_encrypt(data, 2, key);
printf("After encrypt: 0x%08X 0x%08X\n", data[0], data[1]);

xxtea_decrypt(data, 2, key);
printf("After decrypt: 0x%08X 0x%08X\n", data[0], data[1]);

return 0;
}


С таким вот выводом:

Original:      0x12345678 0x9ABCDEF0
After encrypt: 0xB9F221ED 0x71F80F5B
After decrypt: 0x12345678 0x9ABCDEF0


Если кому то надо, то на моей системе такой результат времени запуска бинарника:

Original:      0x12345678 0x9ABCDEF0
After encrypt: 0xB9F221ED 0x71F80F5B
After decrypt: 0x12345678 0x9ABCDEF0

________________________________________________________
Executed in 3.96 millis fish external
usr time 1.09 millis 1.09 millis 0.00 millis
sys time 2.89 millis 1.02 millis 1.87 millis
1👍64🔥2