Как сделать закрытый исходный код
Перейти к содержимому

Как сделать закрытый исходный код

  • автор:

Как сделать закрытый исходный код

Здесь могла бы быть ваша реклама

Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006
Откуда: Israel

Помог: 3 раз(а)

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

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

После этого приходится начинать уточнять этим неграмотным что мне надо.
Они что, сами читать не умеют? А уточнять приходится.
И иногда пока они переварят то что я им скажу проходит и не одна ночь..

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

Поэтому с тех пор я строю свои вопросы по проверенной давным давно схеме:
Что есть
Что нужно получить
Как я пытался
Почему или что у меня не получилось.

На последок как оно происходит на форумах

Цитата:

Новичок: Подскажите пожалуста самый крепкий сорт дерева! Весь инет перерыл, поиском пользовался!
Старожил: Объясни, зачем тебе понадобилось дерево? Сейчас оно в строительстве практически не используется.
Новичок: Я небоскрёб собираюсь строить. Хочу узнать, из какого дерева делать перекрытия между этажами!
Старожил: Какое дерево? Ты вообще соображаешь, что говоришь?
Новичок: Чем мне нравиться этот форум — из двух ответов ниодного конкретного. Одни вопросы неподелу!
Старожил: Не нравится — тебя здесь никто не держит. Но если ты не соображаешь, что из дерева небоскрёбы не строят, то лучше бы тебе сначала школу закончить.
Новичок: Не знаите — лучше молчите! У меня дедушка в деревянном доме живёт! У НЕГО НИЧЕГО НЕ ЛОМАЕТСЯ.
Но у него дом из сосны, а я понимаю, что для небоскрёба нужно дерево прочнее! Поэтому и спрашиваю. А от вас нормального ответа недождёшся.
Прохожий: Самое крепкое дерево — дуб. Вот тебе технология вымачивания дуба в солёной воде, она придаёт дубу особую прочность:
Новичок: Спасибо, братан! То что нужно.

Отредактировано модератором: Uchkuma, 26 Апреля, 2011 — 10:21:12

Открытый VS закрытый исходный код

Начнём с открытого исходного кода. Тут всё понятно — ПО, код которого может изучать каждый и делать свои улучшенные модификации. Но есть одно суеверие — программы с открытым исходным кодом всегда бесплатны. На самом деле не совсем. И с приложений со свободными лицензиями разработчики получают прибыль! Как? Инвестиции, благотворительные пожертвования, реклама в их продуктах, слава.

Популярные приложения и онлайн-сервисы с открытым исходным кодом: Duckduckgo, онлайн-хранилище паролей Bitwarden, Mozilla Firefox, free Pascal, OpenOffice,’ LibreOffice, Google Android.

OpenOffice (справа) и исходный код (слева)

А теперь немного таблицы.

Открытый исходный код

Преимущества

Аудитория, слава, доверие пользователей,

а также сторонние разработчики смогут помочь Вам в усовершенствовании программы.

ПО не всегда выдерживает конкуренцию.

А теперь поговорим про программы с закрытым кодом. Мы все знаем их наизусть:

Windows OS, Adobe Photoshop, Facebook, Microsoft office, Яндекс, Google Gmail

Закрытый исходный код

Преимущества

Слава и популярность.

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

Решать Вам, публиковать ли код программы на обозрение разработчиков или нет.

Можно ли закрыть обратно открытый исходный код?

Эта концепция кажется довольно простой для любого человека, некоторое время работавшего с открытым исходным кодом: проект, однажды выпущенный в виде открытого кода, остаётся открытым навсегда. Конечно, разработчик может решить, что будущие версии проекта будут закрытыми, и иногда такое случалось, но то, что уже выпущено на свободу, отозвать обратно не получится. У интернета нет кнопки «удалить»; опубликовав свой код, и дав миллионам людей потенциальную возможность скачать его, загнать джина обратно в бутылку не получится.

Но что насчёт уважительных причин? Что, если проект превратится во что-то, к чему вы больше не хотите иметь отношения? Возможно, вы отправляли свой код для проекта, имея представление о том, как его будут использовать, а потом правила поменялись. Или же вас забанили на этом проекте, и при этом у людей, поддерживающих его, нет проблем с тем, чтобы оставить ваш значительный вклад в виде кода, даже когда вас выкинули на обочину?

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

Действительно ли невозможно отозвать исходный код, отправленный в проект, выпущенный под такой свободной и открытой лицензией, как GPL? А если можно, то что тогда будет? Что случится, если окажется, что миллиарды устройств, исполняющие у себя ядро Linux, нарушают интеллектуальные права одного разработчика? Эти вопросы крайне важны для интернета и, вероятно, даже нашего образа жизни. Однако ответы на них найти не так легко, как вам могло бы показаться.

Копилефт и права на владение

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

Это порождает концепцию двойного лицензирования: единственный автор программы может выпустить её под несколькими лицензиями одновременно, причём обычно одна из них позволяет делать с программой больше остальных. К примеру, версия программы для Windows может иметь закрытый код, а для Linux – открытый, даже если сам код программ не отличается. Чаще это используется для того, чтобы под одной лицензией программу использовали в коммерческих целях, а под другой, более свободной – в личных.

У некоторых проектов с открытым кодом, обычно больших и имеющих поддержку корпораций, иногда встречается Contributor License Agreement. Этот документ описывает все необходимые дополнительные требования и правила по добавлению кода в проект, и обычно содержит пункт, объясняющий, что человек, вносящий код, передаёт право на него владельцу проекта. К примеру, вот часть такой лицензии от Google:

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

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

Репутационные потери

Так что если разработчик свободен в выборе лицензий для распространения своего кода вплоть до диаметрально противоположных (открытый и закрытый код), и общепризнано, что в отсутствии CLA у него остаётся неоспоримое право на написанный им код, то ситуация становится щекотливой. Разве из этого не следует, что у разработчика остаётся право отозвать своё обещание сделать код открытым, если возникнет ситуация, которая заставит его считать, что код уже не стоит открывать?

Эрик Рэймонд

Эрик Рэймонд, один из основателей инициативы открытого кода, Open Source Initiative, и автор трилогии «Собор и Базар», считает, что у них такое право есть. В записи в списке рассылки Linux Kernel Эрик, в частности, обращается к угрозе, сделанной некоторыми разработчиками, по поводу отзыва их исходного кода из ядра:

Для начала позвольте мне подтвердить, что это не пустая угроза. При основании Open Source Initiative я изучал связанные с этим законы. В США существует прецедентное право, подтверждающее, что репутационные потери, связанные с преобразованием прав участника проекта под GPL, могут рассматриваться в суде. Я не знаю о существовании прецедентного права вне США, но в странах, соблюдающих Бернскую конвенцию без поправок США на «моральные права» [после присоединения к Конвенции США заявили, что моральные права уже защищаются положениями о клевете и, соответственно, не требуют дополнительного регулирования / прим. перев.], эта статья конвенции, вероятно, ещё больше упрочит позицию противников в суде.

Секция 6 Бернской конвенции поясняет, что изначальный автор работы, даже передав свои права другому лицу или организации, может возражать против её использования, если ему кажется, что её используют «в ущерб его чести и репутации». Так что, в теории, недовольны разработчик должен лишь убедить судью, что руководители проекта навредили его репутации, допустим, публично забанив за нарушение правил поведения, в результате чего тот может обязать проект прекратить использовать их код вне зависимости от использовавшейся лицензии.

Критика

Но остаётся вопрос того, может ли разработчик реально «отозвать» права, переданные по GPL? Если мы говорим о GPLv2, которой следует Linux, то наиболее подходящий пункт содержится в секции 4.

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

Интересно, что в GPLv3 правила сильно ужесточились:

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

Некоторые считают, что это отличие может оказаться критически важным. Юридически «отзыв» обычно означает, что соглашение было отозвано тем, кто его предлагал (тут – изначальный разработчик), а «прекращение» просто означает конец действия соглашения. В результате остаётся пространство для интерпретаций, и в принципе, можно утверждать, что поскольку в GPLv2 не указано, что разработчик не может отзывать свои права, эта возможность сохраняется.

Неизученные территории

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

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

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

В итоге, разговоры об отзыве лицензий на открытый код ошибочны. Перефразируя Иена Малькольма, персонажа «Парка Юрского периода»: обиженные разработчики так заняты размышлениями о том, могут они это сделать или нет, что у них не остаётся времени подумать о том, должны ли они это делать вообще. После появления легального прецедента, по которому разработчик может отозвать свой код из открытого проекта, открытое сообщество будет разрушено. У открытого ПО ушли десятилетия на то, чтобы достичь сегодняшнего процветания, но поспешные действия нескольких несчастных разработчиков могут утащить его обратно в область идей, которые лишь хочется воплотить в жизнь.

  • Open source
  • Разработка под Linux
  • Законодательство в IT

Об одном способе защиты исходников Python-программы

Однажды мне пришлось участвовать в разработке одного небольшого проекта для научных расчётов, который разрабатывался на языке программирования Python. Изначально Python был выбран как удобный и гибкий язык для экспериментов, визуализации, быстрого прототипирования и разработки алгоритмов, но в дальнейшем стал основным языком разработки проекта. Надо заметить, что проект был хоть и не большим, но довольно насыщенным технически. Для обеспечения требуемой функциональности, в проекте широко применялись алгоритмы теории графов, математическая оптимизация, линейная алгебра и статистика. Также использовались декораторы, метаклассы и инструменты интроспекции. В процессе разработки пришлось использовать сторонние математические пакеты и библиотеки, например, такие как numpy и scipy, а также многие другие.

Со временем стало ясно, что переписывать проект на компилируемом языке слишком затратно по времени и ресурсам. Скорость работы и потребление памяти не являлись критичными показателями в данном случае и были вполне приемлемыми и достаточными. Поэтому было принято решение оставить всё как есть, и продолжить разработку и поддержку проекта на языке Python. К тому же, документация по большей части уже была написана с использованием Sphinx.

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

Здесь сразу обозначилась новая проблема: как защитить исходные коды нашей Python-библиотеки? Может быть, в ином случае никто бы не стал этим заниматься, я бы уж точно, но в библиотеке были реализованы некоторые ноу-хау, и руководители проекта не хотели, чтобы данные наработки попали к конкурентам. Так как я был одним из исполнителей, мне пришлось озаботиться данной проблемой. Далее я постараюсь рассказать об основной идее, что из этого вышло, и как нам удалось скрыть Python-исходники от лишних глаз.

Что предлагают люди

Как известно, наверное, большинству разработчиков, Python — язык интерпретируемый, динамический с богатыми возможностями интроспекции. Бинарные файлы модулей *.pyc и *.pyo (байт-код) легко декомпилируются, поэтому распространять их в чистом виде нельзя (если уж мы решили не показывать исходники по-настоящему).

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

  • Забить и не париться, всё равно, кому надо — расковыряет;
  • Переписать на компилируемом языке;
  • Сделать обфускацию исходников, например с помощью раз и два;
  • Транслировать все Python-модули в модули расширения (*.pyd) с помощью Cython или Nuitka (как сделал warsoul — автор данной статьи);
  • Заменить опкоды в исходниках Python-интерпретатора и распространять свою сборку, как предлагалhodik.

По многим причинам я отбросил все эти способы как неподходящие. Например, обфускация Python-кода. Ну какая может быть обфускация, когда синтаксис языка построен на отступах, а сам язык пронизан «хитрой интроспекцией»? Транслировать все Python-модули в бинарные модули расширения тоже не представлялось возможным, т. к. проект, напомню, был достаточно сложным технически с использованием множества сторонних пакетов, да и сам состоял из большого числа модулей в многоуровневой иерархии пакетов, которые было утомительно перегонять в *.pyd, а потом ловить баги, вылезающие на ровном месте. Возиться с заменой опкодов не хотелось, так как пришлось бы распространять и поддерживать собственную сборку интерпретатора Python, да ещё и компилировать им Python-модули всех используемых сторонних библиотек.

В какой-то момент мне показалось, что эта идея с защитой Python-исходников бесполезная, надо всё это бросить и убедить руководство, что ничего не выйдет и заняться чем-нибудь полезным. Отдаём *.pyc файлы и ладно, кто там будет разбираться? Убедить не получилось, переписывать библиотеку на C++ никому не хотелось, а проект нужно было сдавать. В итоге всё же кое-что получилось сделать. Об этом, если всё ещё интересно, можно прочитать далее.

Что сделали мы

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

Ход моих мыслей был следующим:

  • Шифруем каким-либо способом все исходники нашей Python-библиотеки, можно их даже перемешать и изменить имена файлов модулей и пакетов;
  • Пишем обвязку для того, чтобы Python-интерпретатор умел загружать и импортировать модули из зашифрованных текстовых файлов (расшифровка, восстановление структуры пакетов и имён файлов, импорт и т. д.);
  • «Прячем» всё это в бинарный модуль расширения (*.pyd), чтобы никто не догадался.

Основная идея, думаю, ясна — это более продвинутая обфускация. Как это сделать? Погуглив, я пришёл к выводу, что сделать это вполне реально и даже достаточно просто. С шифрованием исходников всё понятно, зашифровать и/или обфусцировать файлы можно множеством способов, главное, чтобы там была «каша» и «ничего не понятно», а также всё это должно возвращаться к первоначальному виду неизвестным способом (в случае обфускации). Для приведённого здесь примера я буду использовать Python-модуль base64 для «шифрования». В некритичных случаях можно применять замечательный пакет obfuscate.

Python the Importer Protocol

Как же нам реализовать возможность импортировать модули из зашифрованных файлов? К счастью, в Python реализована система хуков при импорте, которая работает на основе Importer Protocol (PEP 302). Значит эту возможность и будем использовать. Для перехвата импортов используется словарь sys.meta_path , в котором должны храниться объекты finder/loader , реализующие Importer Protocol. Опрос этого словаря всегда происходит до того момента, как будут проверены пути в sys.path .

Для минимальной реализации протокола импорта нужно реализовать два метода: find_module и load_module . Метод find_module отвечает за поиск конкретного модуля/пакета (ведь нам нужно перехватывать импорт только своих модулей, а остальные отдавать на откуп стандартному механизму), а метод load_module , соответственно, загружает конкретный модуль только если он был «найден» в методе find_module .

Итак, вроде бы добрались до сути. Можно привести простой пример. Минимальный пример класса, реализующего Importer Protocol, подходящего для наших целей. Он будет заниматься импортом модулей «зашифрованных» base64 из обычной структуры пакетов (в данном случае для простоты мы просто «зашифровали содержимое» файлов, но никак не меняли их имена и структуру пакетов). Считаем, что расширения файлов для наших модулей будут гордо называться «.b64».

Класс импортёра

#coding=utf-8 import os import sys import imp import base64 EXT = '.b64' #=============================================================================== class Base64Importer(object): """Служит для поиска и импорта python-модулей, кодированных в base64 Класс реализует Import Protocol (PEP 302) для возможности импортирования модулей, зашифрованных в base64 из указанного пакета. """ #--------------------------------------------------------------------------- def __init__(self, root_package_path): self.__modules_info = self.__collect_modules_info(root_package_path) #--------------------------------------------------------------------------- def find_module(self, fullname, path=None): """Метод будет вызван при импорте модулей Если модуль с именем fullname является base64 и находится в заданной папке, данный метод вернёт экземпляр импортёра (finder), либо None, если модуль не является base64. """ if fullname in self.__modules_info: return self return None #--------------------------------------------------------------------------- def load_module(self, fullname): """Метод загружает base64 модуль Если модуль с именем fullname является base64, то метод попытается его загрузить. Возбуждает исключение ImportError в случае любой ошибки. """ if not fullname in self.__modules_info: raise ImportError(fullname) # Для потокобезопасности imp.acquire_lock() try: mod = sys.modules.setdefault(fullname, imp.new_module(fullname)) mod.__file__ .format(self.__class__.__name__) mod.__loader__ = self if self.is_package(fullname): mod.__path__ = [] mod.__package__ = fullname else: mod.__package__ = fullname.rpartition('.')[0] src = self.get_source(fullname) try: exec src in mod.__dict__ except: del sys.modules[fullname] raise ImportError(fullname) finally: imp.release_lock() return mod #--------------------------------------------------------------------------- def is_package(self, fullname): """Возвращает True если fullname является пакетом """ return self.__modules_info[fullname]['ispackage'] #--------------------------------------------------------------------------- def get_source(self, fullname): """Возвращает исходный код модуля fullname в виде строки Метод декодирует исходные коды из base64 """ filename = self.__modules_info[fullname]['filename'] try: with file(filename, 'r') as ifile: src = base64.decodestring(ifile.read()) except IOError: src = '' return src #--------------------------------------------------------------------------- def __collect_modules_info(self, root_package_path): """Собирает информацию о модулях из указанного пакета """ modules = <> p = os.path.abspath(root_package_path) dir_name = os.path.dirname(p) + os.sep for root, _, files in os.walk(p): # Информация о текущем пакете filename = os.path.join(root, '__init__' + EXT) p_fullname = root.rpartition(dir_name)[2].replace(os.sep, '.') modules[p_fullname] = < 'filename': filename, 'ispackage': True ># Информация о модулях в текущем пакете for f in files: if not f.endswith(EXT): continue filename = os.path.join(root, f) fullname = '.'.join([p_fullname, os.path.splitext(f)[0]]) modules[fullname] = < 'filename': filename, 'ispackage': False >return modules 

Как это работает? Первым делом при создании экземпляра класса собирается информация о модулях нашей библиотеки, которую мы «шифруем». Затем при загрузке конкретного модуля, читается нужный «зашифрованный» файл, «расшифровывается» и импортируется с помощью средств модуля imp уже из «расшифрованной» текстовой строки. Как использовать данный класс? Очень легко. Буквально, одной строчкой включается возможность импортировать «зашифрованные» исходники нашей библиотеки, а по сути ставится хук на импорт:

sys.meta_path.append(Base64Importer(root_pkg_path)) 

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

Вот и всё, с этого момента импорт модулей из нашей библиотеки осуществляется с перехватом и «расшифровкой». Наш хук будет дёргаться при любом вызове инструкции import, и если импортируется модули нашей библиотеки, хук будет их обрабатывать и загружать, остальные импорты будут обрабатываться стандартно. Что нам и требовалось для более продвинутой обфускации. Представленный код импортёра и установки хука можно положить уже в *.pyd файл и надеяться на то, что никто не будет его дизассемблировать в надежде понять, что мы тут наворотили. В реальном проекте можно использовать настоящее шифрование, в том числе с использованием аппаратного ключа, что должно повысить надёжность данного метода. Также изменение имён файлов и структуры пакетов может быть полезным для большего запутывания.

Заключение

В качестве заключения хочу сказать, что я противник скрывать исходники, которые нельзя просто так взять и скрыть. В данном случае я не осмелюсь обсуждать этическую сторону вопроса и нужность/полезность сокрытия Python-исходников. Тут я просто представил метод, как это можно сделать и получить какой-то результат. Естественно, это не панацея. Python-код, действительно, невозможно скрыть полностью и от всех. Код модулей всегда можно получить с помощью интроспекции встроенными возможностями языка после их загрузки, например, из переменной sys.modules . Но это уже не так очевидно, как если бы исходники были открыты изначально.

Возможно, что всё, что тут написано и яйца выеденного не стоит — давно известные истины, либо бред сумасшедшего. Но если вышеописанное кому-то может оказаться полезным, я буду рад. Лично для меня данный опыт был полезен, хотя бы потому, что позволил лучше разобраться в мощной и гибкой системе загрузки и импортирования модулей и Importer Protocol. О тех самых штуках, которые чаще всего не требуются разработчикам для написания программ на Python. Всегда интересно узнать что-то новое.

Спасибо за внимание.

UPD 14.08.2013:
По просьбе tangro сделал минимальный проект, в котором демонстрируется описанный способ, но без настоящего шифрования (применены только некие алгоритмы обратимого преобразования).
Скачать zip-архив можно по ссылке. Нужен Python 2.7 x86 под Windows. Запускать нужно скрипт «test_main.py».

UPD 2:
И более интересный пример, в котором производятся некоторые вычисления. Здесь все импорты и вызовы функций из зашифрованных модулей скрыты в бинарном модуле. Скачать архив можно по ссылке.

  • python
  • защита данных
  • защита исходников
  • защита исходных кодов python
  • python importer protocol
  • obfuscation
  • обфускация

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *