talonlib 1.3.1b0
УНППТ™ - Уникальная Необратимая Публичная Подпись Талона

# 🇷🇺 talonlib v1.3 beta

**talonlib** - библиотека, опережающая свое время, использующая запатентованную технологию **УНППТ™** (Уникальная Необратимая Публичная Подпись Талона). Создана **для Минцифры**.

## ВВЕДЕНИЕ
---
talonlib является криптографически защищенной библиотекой и использует **продвинутые импортозамещенные** алгоритмы. Использование библиотеки крайне простое. Сферы применения могут быть разными, но основная - **генерация криптографически стойких** аптечных талончиков (см. пункт "примеры использования"). Для генерации используются данные о железе и текущая дата, поэтому сгенерированный на двух разных устройствах талон будет разным, что значительно усложняет взлом. Открытый исходный код полностью соответствует законам **№159-УК** ("О защите от подделки талонов" от 06.10.2028) и **№115-ФЗ** ("О легализации продаж анальгина для сертифицированных учреждений" от 15.08.1823). Сделано по заказу Минцифры **#ГЛЫШ-ЦАЫС** (в кодировке base32-кириллица).
Особенностью библиотеки является **простота использования** и при этом **широкий низкоуровневый** доступ к параметрам (никаких *magic numbers*)

## УСТАНОВКА
---
**Стандартный метод (PyPI):**
```
pip install talonlib
```

**Если на PyPI нет (TestPyPI):**
```
pip install talonlib --index-url https://test.pypi.org/simple/
```

Ручная установка (тянем с github):
```
git pull https://github.com/mrzff1/talonlib
```

## С ЧЕГО НАЧАТЬ?
---
**Использование из коробки**
```python
from talonlib import security
print(security.generate('test')) # Должно вывести 8 строк из букв
```

**Изменение конфигурации генератора**
```python
from talonlib import security
print(security.generate(
  'test',
  rounds = 3,
  use_date = False,
  return_all_rounds = False)) # Выводит одну строку - результат 3 итераций, при изменении даты вывод не изменится
```

**Получение HWID**
```python
from talonlib import security
print(security.hwid())
```

**Настройка HWID**
```python
from talonlib import security
print(security.hwid(hardware_list = ('CPU_CORES', 'CPU_MAX_FREQ', 'CPU_MIN_FREQ', 'RAM')))
# Все кроме "MAC": у устройств с одинаковым ЦП и объемом ОЗУ будет генерироваться одинаковый HWID
```

**Использование кодировки base32-кириллица**
```python
from talonlib import base32
binary = base32.decode('привет')
print(binary)
print(base32.encode(
  binary,
  block_size=0 # убираем разделение, чтобы вывело "привет" вместо "прив ет"
  ))
```

## БАЗОВАЯ СТРУКТУРА БИБЛИОТЕКИ
---
**Класс info**
Содержит атрибуты:
- лицензию (`LICENSE`)
- версию (`VERSION`)

**Класс base32**
Содержит статические методы:
- `encode()`: бинарные данные (в строковом виде) -> base32
- `decode()`: base32 -> бинарные данные

**Класс security**
Содержит 2 статических метода:
- `hwid()`: возвращает идентификатор устройства (кроссплатформенный)
- `generate()`: генерирует идентификаторы по seed

## СВОЙСТВА МЕТОДОВ
---
**base32.encode**
Кодирует бинарную строку в base32-кириллица. Параметры:
- `binary`: принимает бинарные данные типа str (например, '10' - В)
- `alphabet`: принимает алфавит длиной 32 символа (если длина отличается, вызывает исключение ValueError с причиной `Alphabet must be 32 symbols length`), по умолчанию русский алфавит без "ё"
- `force_len`: дополняет (но не урезает) вывод до указанного числа символов (используйте для стандартизованных выводов, 0 для отключения), по умолчанию `0`
- `separator`: разделитель блоков, по умолчанию `" "`
- `block_size`: размер блока (0 для отключения разделения), по умолчанию `4`

**base32.decode**
Декодирует base32-кириллица в бинарную строку. Параметры:
- `encoded`: принимает данные в кодировке base32.encode, игнорирует все, кроме алфавита
- `alphabet`: принимает алфавит длиной 32 символа (если длина отличается, вызывает исключение ValueError с причиной `Alphabet must be 32 symbols length`), по умолчанию русский алфавит без "ё"
- `force_len`: дополняет (но не урезает) вывод до указанного числа бит (используйте для стандартизованных выводов, 0 для отключения), по умолчанию `0`

**security.hwid**
Собирает данные о железе, склеивает, используя разделитель, хеширует через SHA-512, возвращает хеш
- `hardware_list`: принимает набор (список или кортеж), строковых данных из следующего списка (по умолчанию используются все данные):
 - `"MAC"`: MAC-адрес устройства
 - `"CPU_CORES"`: количество логических ядер процессора
 - `"CPU_MAX_FREQ"`: максимальная частота процессора
 - `"CPU_MIN_FREQ"`: минимальная частота процессора (чаще всего 800/1200 МГц)
 - `"RAM"`: объем ОЗУ на устройстве
- `separator`: принимает разделитель между данными, по умолчанию `""` (выключен)
 
**security.generate** создает цепочку хешей указанной длины применяя salt в виде HWID и текущей даты, выводит все или только последний
- `text`: seed для генератора
- `use_hwid`: передавать ли HWID генератору, по умолчанию `True`
- `use_date`: передавать ли текущую дату генератору, по умолчанию `True`
- `rounds`: количество проходов хеширования, по умолчанию `8`
- `return_all_rounds`: возвращать ли все проходы (True, по умолчанию) или только последний (False)

## ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ (ОБЕРТКИ)
---
**Стандартная обертка, генерируем талон, соблюдаем все законы**
```python
from talonlib import security
from time import time

print(f'{"ГЕНЕРАТОР КРИПТОГРАФИЧЕСКИ СТОЙКИХ УНИКАЛЬНЫХ ТАЛОНЧИКОВ": ^80}')
print(f'{"C ТЕХНОЛОГИЕЙ УНППТ™Ⓒ (УНИКАЛЬНАЯ НЕОБРАТИМАЯ ПУБЛИЧНАЯ ПОДПИСЬ ТАЛОНА™Ⓒ)": ^80}')
print(f'{"ВСЕ ПРАВА ЗАЩИЩЕНЫ": ^80}')
print(f'{"УНППТ™ - СОБСТВЕННОСТЬ МИНЦИФРЫ (ПЕРЕДАНО В РАМКАХ ГОСЗАКУПКИ)": ^80}')
print(f'{"УНППТⒸ - ПРАВО КОПИРОВАНИЯ ЗА МИНЦИФРЫ (ПЕРЕДАНО В РАМКАХ ГОСЗАКУПКИ)": ^80}')
print('\n'*2)
print('Вас приветствует автомат выдачи талонов!')

TICKET = input('Введите полный текст врачебного направления: ')
start_time = time()
print('Ваш уникальный талон:')
print(security.generate(TICKET, return_all_rounds=False))
print(f'Генерация заняла {(time()-start_time)*1000:.3f} мс')
```

**Использование кодирования base32-кириллица ("съедает" всё, кроме русских букв)**
```python
from talonlib import base32
binary = base32.decode('привет')
print(binary)
print(base32.encode(binary,block_size=0))
```

**Получаем HWID (для других проектов)**
```python
from talonlib import security
print(security.hwid())
```

## FAQ (БУДУТ ЗАНОСИТЬСЯ ВОПРОСЫ ИЗ ISSUES)
**Где я могу это использовать?** В любительских или шуточных проектах. Не используйте это в продакшене!

**Могу я дорабатывать библиотеку?** Конечно! Отправляйте pull-реквесты

**Почему это существует?** Это сатира. Рабочая сатира.

**Как декодировать данные из generate обратно?** Никак! Но вы можете их верифицировать (в теории)