Кейс · Бэкенд · TypeScript

qr-svg: QR-коды с нуля

Генератор QR-кодов в SVG на TypeScript без единой runtime-зависимости: весь стандарт ISO/IEC 18004 для версий 1–40 написан в src/qr/ (поле GF(256), Рид-Соломон, чередование блоков, 8 масок со штрафами). API отдаёт SVG, веб-демо показывает предпросмотр, скачивает SVG и PNG и проверяет контраст цветов по WCAG.

  • TypeScript
  • Node.js 24
  • Reed-Solomon
  • GF(256)
  • SVG
  • fast-check
  • vitest
  • axe
  • Docker
  • GitHub Actions

01 · Как выглядит

Скриншоты

Скриншот проекта «qr-svg: QR-коды с нуля» на экране 1280 пикселей
Десктоп, 1280 px
Скриншот проекта «qr-svg: QR-коды с нуля» на экране телефона, 390 пикселей
Телефон, 390 px

02 · О проекте

Что это и зачем

Задача: написать генератор QR-кодов без единой runtime-зависимости и доказать, что он правильный, а не «похож на правильный».

Решение: TypeScript, весь ISO/IEC 18004 для версий 1–40 в src/qr/: поле GF(256), Рид-Соломон, чередование блоков, шаблоны, 8 масок со штрафами. Корректность проверена четырьмя независимыми способами.

Ограничения

Нет Kanji, ECI, смешанных сегментов, Micro QR и структурированного добавления.

Готовой матрицы из самого стандарта в репозитории нет: её роль выполняет сверка с независимой реализацией.

Автовыбор маски у нас и у эталона часто различается (штрафы считаются чуть по-разному), обе маски корректны.

Проект работает на небольшом VPS с демо-данными: без отказоустойчивости и резервных копий.

Что внутри

  • Эталоны стандарта: пример ISO «01234567» в 1-M и разбор «HELLO WORLD» в 1-Q совпадают по байтам коррекции; форматные и версионные слова, позиции выравнивающих узоров
  • Бит в бит с независимой реализацией qrcode-generator: 12 текстов × 4 уровня и 80 случайных строк (fast-check)
  • Сторонний декодер jsQR читает все 160 сочетаний «версия × уровень», кроме 23-L, которую не читает и эталон (матрицы идентичны)
  • Собственный декодер с проверкой нулевых синдромов Рида-Соломона; свойства GF(256) на fast-check
  • 45 тестов; API отдаёт SVG, демо скачивает SVG и PNG и проверяет контраст цветов по WCAG
  • Результат: 200 запросов (четверть тяжёлых, версия 37) p50 131 мс, p95 272 мс; RAM после нагрузки около 180 МиБ

03 · Как запустить

Запуск одной командой

git clone <репозиторий по запросу> qr-svg
cd qr-svg
npm ci && npm test
npm run build && npm start   # http://localhost:8121

04 · Код

Репозиторий приватный

Исходники лежат в приватном репозитории. Напишите в Telegram, открою доступ.

Запросить код