No-code для Python: программа без кода (но работает)

Если когда-нибудь мечтали показать «я ничего не писал», но чтобы программа честно работала – пакет no-code для Python как раз про это. Обычный скрипт превращается в файл из одной строки # coding: no и невидимых Unicode-символов, а при запуске делает то же самое.

Разберёмся, как это устроено, зачем нужно и какие у него «родственники» в мире эзотерического кода.


Что такое no-code для Python

no-code – это Python-пакет и CLI-утилита, которая:

  • берёт обычный some_code.py;
  • кодирует содержимое в последовательность невидимых Unicode-символов;
  • добавляет в начало строку # coding: no;
  • на выходе выдаёт файл, который в редакторе выглядит как «пустой» скрипт, но при запуске выполняет исходный код.

Основная идея родом из шуточной философии «No Code»:

лучший безопасный и надёжный код – это отсутствие кода.

Но иногда всё-таки нужно, чтобы программа что-то делала. Вот no-code и закрывает эту дырку: вы распространяете «программу без кода», которая всё равно работает.


Магия под капотом: невидимые символы и своя «кодировка»

Фокус строится на двух вещах:

  1. Невидимые символы с нулевой шириной
    Используются два Unicode-символа: пробелы нулевой ширины 0x200B и 0x200C.
    • один символ трактуется как 0
    • второй – как 1
    Тело скрипта превращается в двоичную строку и записывается как длинная последовательность этих символов. В редакторе их не видно – файл выглядит почти пустым.
  2. Пользовательская «кодировка» no
    Строка # coding: no говорит интерпретатору Python: загружай этот файл, считая, что исходник закодирован специальной кодировкой no. Механизм coding: в первой или второй строке – стандартный способ указать кодировку исходного кода. Пакет no_code при установке кладёт в site-packages файл no.pth, который автоматически подгружает модуль и регистрирует кодировку no. При запуске Python:
    • видит # coding: no;
    • вызывает обработчик этой кодировки;
    • тот декодирует невидимые символы обратно в обычный Python-текст;
    • и уже этот текст уходит в парсер.

Снаружи файл как будто из одной строки. Внутри – шпионская переписка из нулей и единиц.


Пример: от кода к «ничему» и обратно

Простой скрипт:

# some_code.py
print("Hello, world!")

Дальше включаем магию:

no_code some_code.py > hidden.py

Файл hidden.py в редакторе выглядит примерно так:

# coding: no
# (далее - невидимые Unicode-символы нулевой ширины)

Под «пустой» строкой на самом деле не пробелы, а невидимые Unicode-символы.

Запуск:

python hidden.py

Результат:

Hello, world!

Вернуть исходник:

yes_code hidden.py > restored.py

В restored.py снова окажется нормальный Python-код.


Частичное скрытие: не только целый файл

Если нужно спрятать не весь скрипт, а отдельные куски, в пакете есть две функции:

  • no_code.nothing() – превращает строку или байты в последовательность невидимых символов.
  • no_code.something() – обратное: из невидимых символов извлекает исходные данные.

Этим можно, например:

  • спрятать конфиг или секретную строку прямо в исходнике (для шутки; для реальной безопасности это не решение);
  • зашить пасхалку, которую «увидит» только тот, кто знает про no-code;
  • усложнить жизнь тем, кто читает код на собеседовании.

Команды no_code и yes_code умеют работать и через stdin, так что можно строить цепочки:

echo "print(2 + 2)" | no_code | yes_code | python

Как установить no-code

Нужен Python 3.10+. Установка стандартная (лучше в виртуальном окружении):

python -m venv .venv
source .venv/bin/activate

python -m pip install git+https://github.com/lemonyte/no-code

Если при запуске закодированного скрипта ловите:

  • SyntaxError: invalid syntax – проверьте, что первая строка именно # coding: no;
  • SyntaxError: encoding problem: no – кодировка no не зарегистрировалась при старте. В README проекта описано, как вручную добавить no.pth в site-packages для вашей установки Python.

Это безопасность или просто прикол?

Важно: no-code – шутливый, эзотерический инструмент, а не серьёзная защита.

Да, он:

  • прячет код от беглого взгляда;
  • сбивает с толку человека, который открыл файл и увидел «одну строку»;
  • отлично подходит для демо, докладов и CTF-задач.

Но он не:

  • защищает от реверса (код легко восстановить yes_code или своим декодером);
  • заменяет нормальную обфускацию или шифрование;
  • решает реальные задачи безопасности.

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


Аналоги и вдохновение

У no-code есть яркие «родственники» в других языках:

  • Perl Acme::Bleach – модуль, который превращает код в набор пробелов и табуляций. Открываешь файл – там ничего «нет». Запускаешь – всё работает.
  • JavaScript INVISIBLE.js – библиотека, которая кодирует JS в символы нулевой длины (та же идея).
  • Весь подход перекликается с тезисом «лучший код – тот, который удалось не писать».

no-code аккуратно вписывается в этот пантеон эзотерических игрушек для разработчиков.


Зачем это может пригодиться

Помимо «поржать и забыть», у инструмента есть несколько жизнеспособных сценариев:

  • Демо и доклады – эффектно показать, как Python «исполняет ничего».
  • Учебные материалы – иллюстрировать кодировки, Unicode и механизм coding:.
  • Развлекательные задачки – маленький CTF, где участники должны догадаться, что «пустой» файл на самом деле не пустой.
  • Код-гольф и троллинг друзей – отправить «пустой» файл, который запускается.

Использовать это в боевом продакшене – уже отдельный уровень экстремального спорта.


Итог

no-code для Python – хороший пример того, как из шутки рождается работающий инструмент:

  • скрипт превращается в одну видимую строку # coding: no и стену невидимых символов;
  • при этом программа продолжает выполнять исходный код;
  • всё строится на кастомной кодировке и Unicode-символах нулевой ширины;
  • для точечного «обнукода» есть nothing() / something().

Если хочется поиграться – ставьте в venv и загляните в репозиторий. Только не путайте шутку с защитой: это мем с рабочим CLI, а не обфускация для продакшена.

Источники и ссылки


Комментарии загружаются…