From a75028d68fceeb1d4da38646d0145c3ba2648c4c Mon Sep 17 00:00:00 2001 From: user Date: Sun, 12 Jul 2026 14:06:45 +0400 Subject: [PATCH] Initial commit --- .gitignore | 37 +++++ lab1-Diffie-Hellman/app/app.py | 109 +++++++++++++ lab1-Diffie-Hellman/app/core/__init__.py | 1 + lab1-Diffie-Hellman/app/core/participant.py | 19 +++ lab1-Diffie-Hellman/app/core/prime_utils.py | 12 ++ lab1-Diffie-Hellman/app/core/public_params.py | 30 ++++ .../app/orchestration/param_generator.py | 44 ++++++ lab1-Diffie-Hellman/app/participants/alice.py | 16 ++ lab1-Diffie-Hellman/app/participants/bob.py | 16 ++ lab1-Diffie-Hellman/app/tests/selftest.py | 30 ++++ lab1-Diffie-Hellman/app/utils/__init__.py | 1 + lab1-Diffie-Hellman/app/utils/check_case.py | 21 +++ lab1-Diffie-Hellman/app/utils/format_line.py | 13 ++ lab1-Diffie-Hellman/lab1_Diffie_Hellman.docx | Bin 0 -> 18884 bytes lab2-the-RSA-algorithm/app/app.py | 80 ++++++++++ lab2-the-RSA-algorithm/app/cli/parse_args.py | 104 +++++++++++++ lab2-the-RSA-algorithm/app/core/__init__.py | 0 .../app/core/prime_number.py | 88 +++++++++++ .../app/core/private_key.py | 51 ++++++ lab2-the-RSA-algorithm/app/core/public_key.py | 23 +++ lab2-the-RSA-algorithm/app/modes/auto.py | 68 ++++++++ lab2-the-RSA-algorithm/app/modes/decrypt.py | 55 +++++++ lab2-the-RSA-algorithm/app/modes/encrypt.py | 57 +++++++ lab2-the-RSA-algorithm/app/modes/keygen.py | 133 ++++++++++++++++ lab2-the-RSA-algorithm/app/tests/__init__.py | 0 .../app/tests/test_prime_number.py | 26 ++++ .../app/tests/test_private_key.py | 50 ++++++ .../app/tests/test_public_key.py | 47 ++++++ .../lab2_the_RSA_algorithm.docx | Bin 0 -> 18094 bytes lab3-hash-function/app/app.py | 68 ++++++++ lab3-hash-function/app/cli/parse_args.py | 53 +++++++ .../app/modes/analyze_uniformity.py | 44 ++++++ lab3-hash-function/app/modes/hash_mode.py | 95 +++++++++++ .../app/modes/test_avalanche.py | 39 +++++ .../app/modes/test_collisions.py | 38 +++++ lab3-hash-function/lab3_hash_function.docx | Bin 0 -> 18459 bytes lab4-electronic-digital-signature/app/app.py | 89 +++++++++++ .../app/cli/parse_args.py | 25 +++ .../lab4_electronic_digital_signature.docx | Bin 0 -> 17979 bytes lab5-account-manager-security/app.py | 34 ++++ .../core/__init__.py | 5 + .../core/account_manager.py | 62 ++++++++ .../core/audit_logger.py | 17 ++ .../core/crypto_manager.py | 23 +++ .../core/integrity_checker.py | 26 ++++ .../core/password_hasher.py | 19 +++ .../data/accounts.db | 6 + .../data/accounts.db.hash | 1 + .../data/audit.log.dec | 3 + .../data/audit.log.enc | 1 + .../data/encryption.key | 1 + lab5-account-manager-security/gui/__init__.py | 3 + .../gui/controls_panel.py | 16 ++ .../gui/crypto_tools.py | 92 +++++++++++ .../gui/integrity_tools.py | 73 +++++++++ .../gui/main_window.py | 135 ++++++++++++++++ .../gui/user_list_view.py | 21 +++ lab5-account-manager-security/install.sh | 17 ++ .../lab5-manager.spec | 38 +++++ .../requirements.txt | 2 + lab5-account-manager-security/run.sh | 14 ++ lab5-account-manager-security/test.sh | 14 ++ .../tests/conftest.py | 5 + .../tests/test_account_manager.py | 23 +++ .../tests/test_audit_logger.py | 12 ++ .../tests/test_crypto_manager.py | 17 ++ .../tests/test_integrity_checker.py | 17 ++ .../tests/test_password_hasher.py | 12 ++ lab6-steganography/app.py | 82 ++++++++++ lab6-steganography/cli/__init__.py | 3 + lab6-steganography/cli/parse_args.py | 147 ++++++++++++++++++ lab6-steganography/data/gradient512_1.png | Bin 0 -> 2868 bytes lab6-steganography/data/gradient512_3.png | Bin 0 -> 4377 bytes lab6-steganography/data/gradient64_1.png | Bin 0 -> 118 bytes lab6-steganography/data/like64_1ch.png | Bin 0 -> 444 bytes lab6-steganography/data/schess512_3.1.png | Bin 0 -> 1880 bytes lab6-steganography/data/schess512_3.2.png | Bin 0 -> 1880 bytes lab6-steganography/data/schess512_3.3.png | Bin 0 -> 1880 bytes lab6-steganography/data/schess512_3.4.png | Bin 0 -> 1881 bytes lab6-steganography/data/schess512_3.5.png | Bin 0 -> 1880 bytes lab6-steganography/data/schess512_3.png | Bin 0 -> 3402 bytes lab6-steganography/data/schess64_1.tile32.png | Bin 0 -> 114 bytes lab6-steganography/data/schess64_1.tile8.png | Bin 0 -> 133 bytes lab6-steganography/data/smile64_1.png | Bin 0 -> 959 bytes lab6-steganography/data/start64_1.png | Bin 0 -> 667 bytes lab6-steganography/entities/__init__.py | 21 +++ lab6-steganography/entities/block_grid8.py | 40 +++++ lab6-steganography/entities/channel_view.py | 39 +++++ lab6-steganography/entities/color_space.py | 44 ++++++ lab6-steganography/entities/label64.py | 46 ++++++ lab6-steganography/entities/lsb_row8.py | 31 ++++ lab6-steganography/entities/psnr_metric.py | 22 +++ lab6-steganography/entities/rgb_image512.py | 38 +++++ lab6-steganography/entities/sequence8.py | 55 +++++++ lab6-steganography/entities/ycbcr_image512.py | 50 ++++++ lab6-steganography/generators/__init__.py | 5 + .../generators/chessboard_generator.py | 33 ++++ .../generators/gradient_generator.py | 26 ++++ lab6-steganography/modes/__init__.py | 6 + lab6-steganography/modes/analyze_quality.py | 41 +++++ lab6-steganography/modes/embed_mode.py | 40 +++++ lab6-steganography/modes/extract_mode.py | 38 +++++ lab6-steganography/modes/generate_mode.py | 40 +++++ .../results/00000000/1.result.embed.y.png | Bin 0 -> 70349 bytes .../results/00000000/1.result.extract.cb.png | Bin 0 -> 405 bytes .../results/00000000/1.result.extract.cr.png | Bin 0 -> 233 bytes .../00000000/1.result.extract.y.01010101.png | Bin 0 -> 122 bytes .../results/00000000/1.result.extract.y.png | Bin 0 -> 141 bytes .../results/00000000/2.result.embed.cb.png | Bin 0 -> 68238 bytes .../00000000/2.result.extract.cb.01010101.png | Bin 0 -> 84 bytes .../results/00000000/2.result.extract.cb.png | Bin 0 -> 152 bytes .../results/00000000/2.result.extract.cr.png | Bin 0 -> 211 bytes .../results/00000000/2.result.extract.y.png | Bin 0 -> 353 bytes .../results/00000000/3.result.embed.cr.png | Bin 0 -> 71685 bytes .../results/00000000/3.result.extract.cb.png | Bin 0 -> 400 bytes .../00000000/3.result.extract.cr.00001111.png | Bin 0 -> 144 bytes .../00000000/3.result.extract.cr.00011100.png | Bin 0 -> 201 bytes .../00000000/3.result.extract.cr.00111100.png | Bin 0 -> 127 bytes .../00000000/3.result.extract.cr.01010101.png | Bin 0 -> 144 bytes .../results/00000000/3.result.extract.cr.png | Bin 0 -> 156 bytes .../results/00000000/3.result.extract.y.png | Bin 0 -> 365 bytes .../results/01010101/1.result.embed.y.png | Bin 0 -> 68454 bytes .../results/01010101/1.result.extract.cb.png | Bin 0 -> 329 bytes .../results/01010101/1.result.extract.cr.png | Bin 0 -> 279 bytes .../results/01010101/1.result.extract.y.png | Bin 0 -> 133 bytes .../results/01010101/2.result.embed.cb.png | Bin 0 -> 69855 bytes .../results/01010101/2.result.extract.cb.png | Bin 0 -> 133 bytes .../results/01010101/2.result.extract.cr.png | Bin 0 -> 242 bytes .../results/01010101/2.result.extract.y.png | Bin 0 -> 342 bytes .../results/01010101/3.result.embed.cr.png | Bin 0 -> 72214 bytes .../results/01010101/3.result.extract.cb.png | Bin 0 -> 339 bytes .../results/01010101/3.result.extract.cr.png | Bin 0 -> 133 bytes .../results/01010101/3.result.extract.y.png | Bin 0 -> 376 bytes .../results/01010101/4.result.embed.y.png | Bin 0 -> 7223 bytes .../results/01010101/4.result.extract.y.png | Bin 0 -> 371 bytes .../results/01010101/5.result.embed.cb.png | Bin 0 -> 7126 bytes .../results/01010101/5.result.extract.cb.png | Bin 0 -> 224 bytes .../results/01010101/6.result.embed.cb.png | Bin 0 -> 2505 bytes .../results/01010101/6.result.extract.cb.png | Bin 0 -> 114 bytes .../results/01010101/7.result.embed.cr.png | Bin 0 -> 2342 bytes .../results/01010101/7.result.extract.cr.png | Bin 0 -> 114 bytes .../results/01010101/8.result.embed.y.png | Bin 0 -> 2343 bytes .../results/01010101/8.result.extract.y.png | Bin 0 -> 114 bytes lab6-steganography/steg/__init__.py | 5 + lab6-steganography/steg/component_pipeline.py | 34 ++++ lab6-steganography/steg/embedder.py | 31 ++++ lab6-steganography/steg/extractor.py | 34 ++++ utils/to_1ch_white_bg.py | 33 ++++ 148 files changed, 3275 insertions(+) create mode 100644 .gitignore create mode 100644 lab1-Diffie-Hellman/app/app.py create mode 100644 lab1-Diffie-Hellman/app/core/__init__.py create mode 100644 lab1-Diffie-Hellman/app/core/participant.py create mode 100644 lab1-Diffie-Hellman/app/core/prime_utils.py create mode 100644 lab1-Diffie-Hellman/app/core/public_params.py create mode 100644 lab1-Diffie-Hellman/app/orchestration/param_generator.py create mode 100644 lab1-Diffie-Hellman/app/participants/alice.py create mode 100644 lab1-Diffie-Hellman/app/participants/bob.py create mode 100644 lab1-Diffie-Hellman/app/tests/selftest.py create mode 100644 lab1-Diffie-Hellman/app/utils/__init__.py create mode 100644 lab1-Diffie-Hellman/app/utils/check_case.py create mode 100644 lab1-Diffie-Hellman/app/utils/format_line.py create mode 100644 lab1-Diffie-Hellman/lab1_Diffie_Hellman.docx create mode 100644 lab2-the-RSA-algorithm/app/app.py create mode 100644 lab2-the-RSA-algorithm/app/cli/parse_args.py create mode 100644 lab2-the-RSA-algorithm/app/core/__init__.py create mode 100644 lab2-the-RSA-algorithm/app/core/prime_number.py create mode 100644 lab2-the-RSA-algorithm/app/core/private_key.py create mode 100644 lab2-the-RSA-algorithm/app/core/public_key.py create mode 100644 lab2-the-RSA-algorithm/app/modes/auto.py create mode 100644 lab2-the-RSA-algorithm/app/modes/decrypt.py create mode 100644 lab2-the-RSA-algorithm/app/modes/encrypt.py create mode 100644 lab2-the-RSA-algorithm/app/modes/keygen.py create mode 100644 lab2-the-RSA-algorithm/app/tests/__init__.py create mode 100644 lab2-the-RSA-algorithm/app/tests/test_prime_number.py create mode 100644 lab2-the-RSA-algorithm/app/tests/test_private_key.py create mode 100644 lab2-the-RSA-algorithm/app/tests/test_public_key.py create mode 100644 lab2-the-RSA-algorithm/lab2_the_RSA_algorithm.docx create mode 100644 lab3-hash-function/app/app.py create mode 100644 lab3-hash-function/app/cli/parse_args.py create mode 100644 lab3-hash-function/app/modes/analyze_uniformity.py create mode 100644 lab3-hash-function/app/modes/hash_mode.py create mode 100644 lab3-hash-function/app/modes/test_avalanche.py create mode 100644 lab3-hash-function/app/modes/test_collisions.py create mode 100644 lab3-hash-function/lab3_hash_function.docx create mode 100644 lab4-electronic-digital-signature/app/app.py create mode 100644 lab4-electronic-digital-signature/app/cli/parse_args.py create mode 100644 lab4-electronic-digital-signature/lab4_electronic_digital_signature.docx create mode 100644 lab5-account-manager-security/app.py create mode 100644 lab5-account-manager-security/core/__init__.py create mode 100644 lab5-account-manager-security/core/account_manager.py create mode 100644 lab5-account-manager-security/core/audit_logger.py create mode 100644 lab5-account-manager-security/core/crypto_manager.py create mode 100644 lab5-account-manager-security/core/integrity_checker.py create mode 100644 lab5-account-manager-security/core/password_hasher.py create mode 100644 lab5-account-manager-security/data/accounts.db create mode 100644 lab5-account-manager-security/data/accounts.db.hash create mode 100644 lab5-account-manager-security/data/audit.log.dec create mode 100644 lab5-account-manager-security/data/audit.log.enc create mode 100644 lab5-account-manager-security/data/encryption.key create mode 100644 lab5-account-manager-security/gui/__init__.py create mode 100644 lab5-account-manager-security/gui/controls_panel.py create mode 100644 lab5-account-manager-security/gui/crypto_tools.py create mode 100644 lab5-account-manager-security/gui/integrity_tools.py create mode 100644 lab5-account-manager-security/gui/main_window.py create mode 100644 lab5-account-manager-security/gui/user_list_view.py create mode 100755 lab5-account-manager-security/install.sh create mode 100644 lab5-account-manager-security/lab5-manager.spec create mode 100644 lab5-account-manager-security/requirements.txt create mode 100755 lab5-account-manager-security/run.sh create mode 100755 lab5-account-manager-security/test.sh create mode 100644 lab5-account-manager-security/tests/conftest.py create mode 100644 lab5-account-manager-security/tests/test_account_manager.py create mode 100644 lab5-account-manager-security/tests/test_audit_logger.py create mode 100644 lab5-account-manager-security/tests/test_crypto_manager.py create mode 100644 lab5-account-manager-security/tests/test_integrity_checker.py create mode 100644 lab5-account-manager-security/tests/test_password_hasher.py create mode 100644 lab6-steganography/app.py create mode 100644 lab6-steganography/cli/__init__.py create mode 100644 lab6-steganography/cli/parse_args.py create mode 100644 lab6-steganography/data/gradient512_1.png create mode 100644 lab6-steganography/data/gradient512_3.png create mode 100644 lab6-steganography/data/gradient64_1.png create mode 100644 lab6-steganography/data/like64_1ch.png create mode 100644 lab6-steganography/data/schess512_3.1.png create mode 100644 lab6-steganography/data/schess512_3.2.png create mode 100644 lab6-steganography/data/schess512_3.3.png create mode 100644 lab6-steganography/data/schess512_3.4.png create mode 100644 lab6-steganography/data/schess512_3.5.png create mode 100644 lab6-steganography/data/schess512_3.png create mode 100644 lab6-steganography/data/schess64_1.tile32.png create mode 100644 lab6-steganography/data/schess64_1.tile8.png create mode 100644 lab6-steganography/data/smile64_1.png create mode 100644 lab6-steganography/data/start64_1.png create mode 100644 lab6-steganography/entities/__init__.py create mode 100644 lab6-steganography/entities/block_grid8.py create mode 100644 lab6-steganography/entities/channel_view.py create mode 100644 lab6-steganography/entities/color_space.py create mode 100644 lab6-steganography/entities/label64.py create mode 100644 lab6-steganography/entities/lsb_row8.py create mode 100644 lab6-steganography/entities/psnr_metric.py create mode 100644 lab6-steganography/entities/rgb_image512.py create mode 100644 lab6-steganography/entities/sequence8.py create mode 100644 lab6-steganography/entities/ycbcr_image512.py create mode 100644 lab6-steganography/generators/__init__.py create mode 100644 lab6-steganography/generators/chessboard_generator.py create mode 100644 lab6-steganography/generators/gradient_generator.py create mode 100644 lab6-steganography/modes/__init__.py create mode 100644 lab6-steganography/modes/analyze_quality.py create mode 100644 lab6-steganography/modes/embed_mode.py create mode 100644 lab6-steganography/modes/extract_mode.py create mode 100644 lab6-steganography/modes/generate_mode.py create mode 100644 lab6-steganography/results/00000000/1.result.embed.y.png create mode 100644 lab6-steganography/results/00000000/1.result.extract.cb.png create mode 100644 lab6-steganography/results/00000000/1.result.extract.cr.png create mode 100644 lab6-steganography/results/00000000/1.result.extract.y.01010101.png create mode 100644 lab6-steganography/results/00000000/1.result.extract.y.png create mode 100644 lab6-steganography/results/00000000/2.result.embed.cb.png create mode 100644 lab6-steganography/results/00000000/2.result.extract.cb.01010101.png create mode 100644 lab6-steganography/results/00000000/2.result.extract.cb.png create mode 100644 lab6-steganography/results/00000000/2.result.extract.cr.png create mode 100644 lab6-steganography/results/00000000/2.result.extract.y.png create mode 100644 lab6-steganography/results/00000000/3.result.embed.cr.png create mode 100644 lab6-steganography/results/00000000/3.result.extract.cb.png create mode 100644 lab6-steganography/results/00000000/3.result.extract.cr.00001111.png create mode 100644 lab6-steganography/results/00000000/3.result.extract.cr.00011100.png create mode 100644 lab6-steganography/results/00000000/3.result.extract.cr.00111100.png create mode 100644 lab6-steganography/results/00000000/3.result.extract.cr.01010101.png create mode 100644 lab6-steganography/results/00000000/3.result.extract.cr.png create mode 100644 lab6-steganography/results/00000000/3.result.extract.y.png create mode 100644 lab6-steganography/results/01010101/1.result.embed.y.png create mode 100644 lab6-steganography/results/01010101/1.result.extract.cb.png create mode 100644 lab6-steganography/results/01010101/1.result.extract.cr.png create mode 100644 lab6-steganography/results/01010101/1.result.extract.y.png create mode 100644 lab6-steganography/results/01010101/2.result.embed.cb.png create mode 100644 lab6-steganography/results/01010101/2.result.extract.cb.png create mode 100644 lab6-steganography/results/01010101/2.result.extract.cr.png create mode 100644 lab6-steganography/results/01010101/2.result.extract.y.png create mode 100644 lab6-steganography/results/01010101/3.result.embed.cr.png create mode 100644 lab6-steganography/results/01010101/3.result.extract.cb.png create mode 100644 lab6-steganography/results/01010101/3.result.extract.cr.png create mode 100644 lab6-steganography/results/01010101/3.result.extract.y.png create mode 100644 lab6-steganography/results/01010101/4.result.embed.y.png create mode 100644 lab6-steganography/results/01010101/4.result.extract.y.png create mode 100644 lab6-steganography/results/01010101/5.result.embed.cb.png create mode 100644 lab6-steganography/results/01010101/5.result.extract.cb.png create mode 100644 lab6-steganography/results/01010101/6.result.embed.cb.png create mode 100644 lab6-steganography/results/01010101/6.result.extract.cb.png create mode 100644 lab6-steganography/results/01010101/7.result.embed.cr.png create mode 100644 lab6-steganography/results/01010101/7.result.extract.cr.png create mode 100644 lab6-steganography/results/01010101/8.result.embed.y.png create mode 100644 lab6-steganography/results/01010101/8.result.extract.y.png create mode 100644 lab6-steganography/steg/__init__.py create mode 100644 lab6-steganography/steg/component_pipeline.py create mode 100644 lab6-steganography/steg/embedder.py create mode 100644 lab6-steganography/steg/extractor.py create mode 100644 utils/to_1ch_white_bg.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2335493 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Python cache +__pycache__/ +*.py[cod] +*$py.class + +# Virtual environments +venv/ +.venv/ +env/ +ENV/ + +# Environment variables +.env + +# Build files +build/ +dist/ +*.egg-info/ + +# Jupyter Notebook +.ipynb_checkpoints/ + +# Test and coverage +.pytest_cache/ +.coverage +htmlcov/ + +# IDE +.vscode/ +.idea/ + +# OS files +.DS_Store +Thumbs.db + +# Logs +*.log diff --git a/lab1-Diffie-Hellman/app/app.py b/lab1-Diffie-Hellman/app/app.py new file mode 100644 index 0000000..da64872 --- /dev/null +++ b/lab1-Diffie-Hellman/app/app.py @@ -0,0 +1,109 @@ +from argparse import ArgumentParser +from secrets import randbelow + +from utils.check_case import check_case +from utils.format_line import format_line +from orchestration.param_generator import ParamGenerator + + +def _random_secret() -> int: + # 2..9999 включительно (меньше 10000, исключаем 0/1) + return 2 + randbelow(9998) + + +def run_auto(count: int) -> None: + """ + Автоматический режим: + - случайно генерируем (p, q, g); + - случайно выбираем x, y (<10000); + - вычисляем K и проверяем через check_case; + - печатаем результат через format_line + """ + for i in range(1, count + 1): + p, q, g = ParamGenerator.generate() # q выводим для информации + x = _random_secret() + y = _random_secret() + + # Вычислим K заранее, чтобы передать как эталон в check_case + # (тем самым используем общий хелпер единообразно) + ok, (A, B, K_a, K_b) = check_case(p, g, x, y, K_expected=None) + # Когда K_expected=None, наша старая версия check_case + # сравнивала строго с эталоном. Если у тебя именно так, + # просто заменим на повторный вызов с «эталоном = K_a» + if K_a != K_b: + ok = False + else: + ok, (A, B, K_a, K_b) = check_case(p, g, x, y, K_expected=K_a) + + print(f"[auto #{i}] p={p} q={q} g={g}") + print(format_line(i, A, B, K_a, K_b, ok)) + + +def run_manual(p: int, g: int, x: int, y: int, k: int | None) -> None: + """ + Ручной режим: + - принимаем p, g, x, y; + - если указан k — проверяем с эталоном; + - если k не указан — просто считаем и показываем + """ + if k is None: + ok, (A, B, K_a, K_b) = check_case(p, g, x, y, K_expected=None) + ok = (K_a == K_b) + print(f"[manual] p={p} g={g}") + print(format_line(1, A, B, K_a, K_b, ok)) + else: + ok, (A, B, K_a, K_b) = check_case(p, g, x, y, K_expected=k) + print(f"[manual] p={p} g={g} K_expected={k}") + print(format_line(1, A, B, K_a, K_b, ok)) + + +def parse_args(): + ap = ArgumentParser( + description=( + "Demo Diffie–Hellman: режимы manual и auto\n" + "Auto: случайно генерирует (p,q,g) и секреты (<10000)\n" + "Manual: используется заданный набор параметров" + ) + ) + ap.add_argument( + "--mode", + choices=["auto", "manual"], + default="auto", + help="Режим работы (auto|manual). По умолчанию auto", + ) + ap.add_argument( + "--count", + type=int, + default=5, + help="Сколько генераций в auto-режиме (по умолчанию 5)", + ) + ap.add_argument("--p", type=int, help="Модуль (prime_modulus) в manual") + ap.add_argument("--g", type=int, help="Генератор (generator) в manual") + ap.add_argument("--x", type=int, help="Секрет Алисы (<10000) в manual") + ap.add_argument("--y", type=int, help="Секрет Боба (<10000) в manual") + ap.add_argument( + "--k", + type=int, + help="Эталонный общий ключ для проверки в manual (необязательно)", + ) + return ap.parse_args() + + +def main(): + args = parse_args() + if args.mode == "auto": + run_auto(count=args.count) + return + + # manual + missing = [n for n, v in [("p", args.p), ("g", args.g), + ("x", args.x), ("y", args.y)] if v is None] + if missing: + need = ", ".join(missing) + raise SystemExit(f"manual-режим: необходимо указать параметры: {need}") + run_manual(p=args.p, g=args.g, x=args.x, y=args.y, k=args.k) + + +if __name__ == "__main__": + main() + diff --git a/lab1-Diffie-Hellman/app/core/__init__.py b/lab1-Diffie-Hellman/app/core/__init__.py new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/lab1-Diffie-Hellman/app/core/__init__.py @@ -0,0 +1 @@ +# diff --git a/lab1-Diffie-Hellman/app/core/participant.py b/lab1-Diffie-Hellman/app/core/participant.py new file mode 100644 index 0000000..55945e3 --- /dev/null +++ b/lab1-Diffie-Hellman/app/core/participant.py @@ -0,0 +1,19 @@ +from secrets import randbelow +from .public_params import PublicParams + + +class Participant: + """ + Участник протокола (Алиса или Боб). + Держит свой секрет, публикует g^secret mod p, + умеет вычислять общий ключ. + """ + + def __init__(self, params: PublicParams, secret: int | None = None): + self.params = params + self.secret = secret if secret is not None else (2 + randbelow(9998)) + self.public_value = pow(self.params.generator, + self.secret, self.params.prime_modulus) + + def compute_shared_key(self, other_public: int) -> int: + return pow(other_public, self.secret, self.params.prime_modulus) diff --git a/lab1-Diffie-Hellman/app/core/prime_utils.py b/lab1-Diffie-Hellman/app/core/prime_utils.py new file mode 100644 index 0000000..363c3ab --- /dev/null +++ b/lab1-Diffie-Hellman/app/core/prime_utils.py @@ -0,0 +1,12 @@ +def is_prime(n: int) -> bool: + """Проверка на простоту""" + if n < 2: + return False + if n % 2 == 0: + return n == 2 + d = 3 + while d * d <= n: + if n % d == 0: + return False + d += 2 + return True diff --git a/lab1-Diffie-Hellman/app/core/public_params.py b/lab1-Diffie-Hellman/app/core/public_params.py new file mode 100644 index 0000000..4fb6f71 --- /dev/null +++ b/lab1-Diffie-Hellman/app/core/public_params.py @@ -0,0 +1,30 @@ +from dataclasses import dataclass +from .prime_utils import is_prime + + +@dataclass(frozen=True) +class PublicParams: + """ + Публичные параметры протокола: + - prime_modulus: простое число p + - generator: порождающий элемент g + """ + prime_modulus: int + generator: int + + def __post_init__(self): + p = self.prime_modulus + g = self.generator + + # Проверка простоты модуля + if not is_prime(p): + raise ValueError(f"prime_modulus={p} не является простым числом") + + # Проверка допустимости генератора + if g <= 1 or g >= p - 1: + raise ValueError( + f"generator={g} вне допустимого диапазона (2..p-2)") + + # Проверка, что генератор не сворачивается в малую подгруппу + if pow(g, (p - 1) // 2, p) == 1: + raise ValueError(f"generator={g} не является корректным для p={p}") diff --git a/lab1-Diffie-Hellman/app/orchestration/param_generator.py b/lab1-Diffie-Hellman/app/orchestration/param_generator.py new file mode 100644 index 0000000..2351067 --- /dev/null +++ b/lab1-Diffie-Hellman/app/orchestration/param_generator.py @@ -0,0 +1,44 @@ +from secrets import randbelow, randbits +from core.prime_utils import is_prime + + +class ParamGenerator: + """ + Генератор параметров протокола Диффи–Хеллмана. + Возвращает тройку (p, q, g): + - p = 2*q + 1, где p и q простые + - g — корректный генератор для группы по модулю p + """ + + @staticmethod + def generate() -> tuple[int, int, int]: + """ + Случайным образом выбирает размерность (кол-во бит) для q, + подбирает безопасное простое p и генератор g. + Возвращает (p, q, g). + """ + # Размер числа выбираем случайно от 8 до 16 бит (от 256 до 65 535) + bits = 8 + randbelow(9) + + # Генерация безопасного простого + while True: + q = randbits(bits - 1) | 1 # нечётное число + if not is_prime(q): + continue + p = 2 * q + 1 + if not is_prime(p): + continue + # Найдём генератор + g = ParamGenerator._find_generator(p, q) + return p, q, g + + @staticmethod + def _find_generator(p: int, q: int) -> int: + """ + Ищет генератор g: минимальное число 2..p-2, + для которого g^q mod p != 1. + """ + for g in range(2, p - 1): + if pow(g, q, p) != 1: + return g + raise ValueError("Не удалось найти генератор для p") diff --git a/lab1-Diffie-Hellman/app/participants/alice.py b/lab1-Diffie-Hellman/app/participants/alice.py new file mode 100644 index 0000000..8734068 --- /dev/null +++ b/lab1-Diffie-Hellman/app/participants/alice.py @@ -0,0 +1,16 @@ +from core.participant import Participant +from core.public_params import PublicParams + + +class Alice: + def __init__(self, params: PublicParams, secret: int | None = None): + self.party = Participant(params, secret=secret) + self.shared_key = None + + @property + def A(self) -> int: + return self.party.public_value + + def receive_B(self, B: int): + self.shared_key = self.party.compute_shared_key(B) + return self.shared_key diff --git a/lab1-Diffie-Hellman/app/participants/bob.py b/lab1-Diffie-Hellman/app/participants/bob.py new file mode 100644 index 0000000..eb5be4a --- /dev/null +++ b/lab1-Diffie-Hellman/app/participants/bob.py @@ -0,0 +1,16 @@ +from core.participant import Participant +from core.public_params import PublicParams + + +class Bob: + def __init__(self, params: PublicParams, secret: int | None = None): + self.party = Participant(params, secret=secret) + self.shared_key = None + + @property + def B(self) -> int: + return self.party.public_value + + def receive_A(self, A: int): + self.shared_key = self.party.compute_shared_key(A) + return self.shared_key diff --git a/lab1-Diffie-Hellman/app/tests/selftest.py b/lab1-Diffie-Hellman/app/tests/selftest.py new file mode 100644 index 0000000..a61538b --- /dev/null +++ b/lab1-Diffie-Hellman/app/tests/selftest.py @@ -0,0 +1,30 @@ +from utils.check_case import check_case +from utils.format_line import format_line + +CASES = [ + (29, 2, 60, 82, 23), + (53, 2, 20, 77, 42), + (73, 5, 37, 47, 31), + (31, 3, 31, 51, 15), + (41, 6, 31, 98, 8), + (19, 2, 20, 73, 4), + (71, 7, 30, 89, 45), + (109, 6, 7, 14, 84), + (131, 2, 88, 15, 52), + (97, 5, 58, 68, 6), +] + + +def main(): + all_ok = True + for i, case in enumerate(CASES, start=1): + ok, (A, B, K_a, K_b) = check_case(*case) + print(format_line(i, A, B, K_a, K_b, ok)) + if not ok: + all_ok = False + if not all_ok: + raise SystemExit(1) + + +if __name__ == "__main__": + main() diff --git a/lab1-Diffie-Hellman/app/utils/__init__.py b/lab1-Diffie-Hellman/app/utils/__init__.py new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/lab1-Diffie-Hellman/app/utils/__init__.py @@ -0,0 +1 @@ +# diff --git a/lab1-Diffie-Hellman/app/utils/check_case.py b/lab1-Diffie-Hellman/app/utils/check_case.py new file mode 100644 index 0000000..2114248 --- /dev/null +++ b/lab1-Diffie-Hellman/app/utils/check_case.py @@ -0,0 +1,21 @@ +from core.public_params import PublicParams +from core.participant import Participant + + +def check_case(prime_modulus, generator, x, y, K_expected): + """ + Строит участников, имитирует обмен и проверяет совпадение ключа с эталоном. + Возвращает: ok (bool), (A, B, K_a, K_b) + """ + params = PublicParams(prime_modulus, generator) + alice = Participant(params, secret=x) + bob = Participant(params, secret=y) + + A = alice.public_value + B = bob.public_value + + K_a = alice.compute_shared_key(B) + K_b = bob.compute_shared_key(A) + + ok = (K_a == K_b == K_expected) + return ok, (A, B, K_a, K_b) diff --git a/lab1-Diffie-Hellman/app/utils/format_line.py b/lab1-Diffie-Hellman/app/utils/format_line.py new file mode 100644 index 0000000..9275fcc --- /dev/null +++ b/lab1-Diffie-Hellman/app/utils/format_line.py @@ -0,0 +1,13 @@ +def format_line(i, A, B, K_a, K_b, ok): + """ + Форматирует вывод строки для теста. + """ + status = "OK" if ok else "FAIL" + return ( + f"#{i:>2}: " + f"A={A:>6} " + f"B={B:>6} " + f"K_A={K_a:>6} " + f"K_B={K_b:>6} " + f"-> {status}" + ) diff --git a/lab1-Diffie-Hellman/lab1_Diffie_Hellman.docx b/lab1-Diffie-Hellman/lab1_Diffie_Hellman.docx new file mode 100644 index 0000000000000000000000000000000000000000..fdf153e517a072d9f808ceeeb7f5a4c16cd69cdb GIT binary patch literal 18884 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 literal 0 HcmV?d00001 diff --git a/lab2-the-RSA-algorithm/app/app.py b/lab2-the-RSA-algorithm/app/app.py new file mode 100644 index 0000000..2122f32 --- /dev/null +++ b/lab2-the-RSA-algorithm/app/app.py @@ -0,0 +1,80 @@ +import json +import sys + +from cli.parse_args import parse_args + + +def main() -> int: + args = parse_args() + + try: + if args.cmd == "keygen": + # Класс для режима генерации ключей + from modes.keygen import KeygenMode + + runner = KeygenMode() + result = runner.run( + p=args.p, + q=args.q, + min=args.min, + max=args.max, + bits=args.bits, + seed=args.seed, + ) + + elif args.cmd == "encrypt": + # Класс для режима шифрования + from modes.encrypt import EncryptMode + + runner = EncryptMode() + result = runner.run( + text=args.text, + m=args.m, + n=args.n, + e=args.e, + ) + + elif args.cmd == "decrypt": + # Класс для режима расшифрования + from modes.decrypt import DecryptMode + + runner = DecryptMode() + result = runner.run( + c=args.c, + n=args.n, + d=args.d, + ) + + elif args.cmd == "auto": + from modes.auto import AutoMode + runner = AutoMode() + result = runner.run( + text=args.text, + m=args.m, + p=args.p, + q=args.q, + min=args.min, + max=args.max, + bits=args.bits, + seed=args.seed, + ) + + else: + raise RuntimeError(f"Неизвестная команда: {args.cmd}") + + # Печать результата, если он что-то возвращает + if result is not None: + if isinstance(result, (dict, list)): + print(json.dumps(result, ensure_ascii=False, indent=2)) + else: + print(result) + + return 0 + + except Exception as exc: + print(f"Ошибка: {exc}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + main() diff --git a/lab2-the-RSA-algorithm/app/cli/parse_args.py b/lab2-the-RSA-algorithm/app/cli/parse_args.py new file mode 100644 index 0000000..fb4d346 --- /dev/null +++ b/lab2-the-RSA-algorithm/app/cli/parse_args.py @@ -0,0 +1,104 @@ +from argparse import ArgumentParser, RawDescriptionHelpFormatter + + +def _int_auto(x: str) -> int: + return int(x, 0) + + +def parse_args(argv=None): + ap = ArgumentParser( + description=( + "RSA Algorithm CLI with refactored argument handling.\n\n" + "Examples:\n" + " app.py keygen --bits 8\n" + " app.py encrypt --text \"RSA\" --e 17 --n 0xca1\n" + " app.py decrypt --c 0x357 --n 0xca1 --d 0xac1\n" + " app.py auto --text \"RSA\" --bits 8\n" + " app.py auto --m 65 --min 100 --max 1000\n" + ), + formatter_class=RawDescriptionHelpFormatter, + ) + + sub = ap.add_subparsers(dest="cmd", required=True) + + # -------- parents to deduplicate args -------- + # Общие параметры генерации ключей (используются в keygen и auto) + parent_keygen = ArgumentParser(add_help=False) + parent_keygen.add_argument("--p", type=_int_auto, help="Простое число p.") + parent_keygen.add_argument("--q", type=_int_auto, help="Простое число q.") + parent_keygen.add_argument( + "--min", + type=int, + default=2, + help="Нижняя граница поиска простых (при случайной генерации диапазоном).", + ) + parent_keygen.add_argument( + "--max", + type=int, + help="Верхняя граница поиска простых (при случайной генерации диапазоном).", + ) + parent_keygen.add_argument( + "--bits", + type=int, + help="Количество бит для случайной генерации простых (альтернатива min/max).", + ) + parent_keygen.add_argument( + "--seed", type=int, help="Seed для ГСЧ (опционально, для воспроизводимости)." + ) + + # Общий модуль n (используется в encrypt и decrypt) + parent_n = ArgumentParser(add_help=False) + parent_n.add_argument("--n", type=_int_auto, + required=True, help="Модуль n.") + + # Общий ввод открытого сообщения (используется в encrypt и auto) + parent_plain = ArgumentParser(add_help=False) + plain_group = parent_plain.add_mutually_exclusive_group(required=True) + plain_group.add_argument( + "--text", type=str, help="Открытый текст (ASCII).") + plain_group.add_argument( + "--m", type=_int_auto, help="Открытое сообщение как неотрицательное целое." + ) + + # -------- keygen -------- + sub.add_parser( + "keygen", + help="Сгенерировать приватный (p, q, d, n) и публичный (e, n) ключи.", + formatter_class=RawDescriptionHelpFormatter, + parents=[parent_keygen], + ) + + # -------- encrypt -------- + sp_enc = sub.add_parser( + "encrypt", + help="Зашифровать сообщение публичным ключом (e, n).", + formatter_class=RawDescriptionHelpFormatter, + parents=[parent_n, parent_plain], + ) + sp_enc.add_argument( + "--e", type=_int_auto, required=True, help="Публичная экспонента e (простое)." + ) + + # -------- decrypt -------- + sp_dec = sub.add_parser( + "decrypt", + help="Расшифровать шифртекст приватным ключом (n, d).", + formatter_class=RawDescriptionHelpFormatter, + parents=[parent_n], + ) + sp_dec.add_argument( + "--c", type=_int_auto, required=True, help="Шифртекст как неотрицательное целое." + ) + sp_dec.add_argument( + "--d", type=_int_auto, required=True, help="Приватная экспонента d." + ) + + # -------- auto -------- + sub.add_parser( + "auto", + help="Автоматический режим: как keygen + обязательный ввод сообщения.", + formatter_class=RawDescriptionHelpFormatter, + parents=[parent_keygen, parent_plain], + ) + + return ap.parse_args(argv) diff --git a/lab2-the-RSA-algorithm/app/core/__init__.py b/lab2-the-RSA-algorithm/app/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lab2-the-RSA-algorithm/app/core/prime_number.py b/lab2-the-RSA-algorithm/app/core/prime_number.py new file mode 100644 index 0000000..1953fd6 --- /dev/null +++ b/lab2-the-RSA-algorithm/app/core/prime_number.py @@ -0,0 +1,88 @@ +import random +import math + + +class PrimeNumber: + """ + Класс-обёртка для простого числа. + Контракт: внутри всегда хранится валидное простое число. + """ + + MAX_ATTEMPTS: int = 1000 # лимит попыток генерации + + def __init__(self, value: int): + if not self._is_prime(value): + raise ValueError(f"Число {value} не является простым") + self._value = value + + @classmethod + def from_value(cls, value: int) -> "PrimeNumber": + """Фабричный метод: создать простое число из заданного значения.""" + return cls(value) + + @classmethod + def random( + cls, + min_value: int | None = None, + max_value: int | None = None, + seed: int | None = None + ) -> "PrimeNumber": + """ + Случайное простое число из диапазона [min_value, max_value]. + Если seed указан, ГСЧ инициализируется для воспроизводимости. + """ + if min_value < 2: + raise ValueError("Нижняя граница min_value должна быть ≥ 2") + if min_value > max_value: + raise ValueError("min_value не может быть больше max_value") + + if seed is not None: + random.seed(seed) + + for _ in range(cls.MAX_ATTEMPTS): + candidate = random.randint(min_value, max_value) + if cls._is_prime(candidate): + return cls(candidate) + + raise ValueError( + f"Не удалось найти простое число в диапазоне [{ + min_value}, {max_value}] " + f"за {cls.MAX_ATTEMPTS} попыток" + ) + + @classmethod + def random_bits(cls, bits: int, seed: int | None = None) -> "PrimeNumber": + if bits < 2: + raise ValueError("Количество бит должно быть не меньше 2") + + # Нижняя граница — 2^(bits-1), верхняя — 2^bits - 1 + min_value = 1 << (bits - 1) + max_value = (1 << bits) - 1 + + return cls.random( + min_value=min_value, + max_value=max_value, + seed=seed, + ) + + @property + def value(self) -> int: + return self._value + + def __repr__(self) -> str: + return f"PrimeNumber({self._value})" + + @staticmethod + def _is_prime(n: int) -> bool: + """Проверка на простоту (НУ ОООЧЕНЬ МЕДЛЕННАЯ).""" + if n < 2: + return False + if n in (2, 3): + return True + if n % 2 == 0: + return False + limit = int(math.isqrt(n)) + 1 + for i in range(3, limit, 2): + if n % i == 0: + return False + return True diff --git a/lab2-the-RSA-algorithm/app/core/private_key.py b/lab2-the-RSA-algorithm/app/core/private_key.py new file mode 100644 index 0000000..7d5248d --- /dev/null +++ b/lab2-the-RSA-algorithm/app/core/private_key.py @@ -0,0 +1,51 @@ +from math import gcd +from .prime_number import PrimeNumber +from .public_key import PublicKey + + +class PrivateKey: + """ + Закрытый ключ RSA. + p1, p2 — экземпляры PrimeNumber. + e — экземпляр PrimeNumber (открытая степень). + n = p1 * p2 (int). + """ + + def __init__(self, p1: PrimeNumber, p2: PrimeNumber): + if not isinstance(p1, PrimeNumber) or not isinstance(p2, PrimeNumber): + raise TypeError("p1 и p2 должны быть экземплярами PrimeNumber") + if p1.value == p2.value: + raise ValueError("p1 и p2 должны быть разными простыми") + + self.p1 = p1 + self.p2 = p2 + self.n = p1.value * p2.value + self.phi = (p1.value - 1) * (p2.value - 1) + + self.e = self._choose_e() + self.d = self._compute_d() + + def _choose_e(self) -> PrimeNumber: + # ищем простое e, взаимнопростое с φ(n) + candidate = 3 + while candidate < self.phi: + if gcd(candidate, self.phi) == 1 and PrimeNumber._is_prime(candidate): + return PrimeNumber(candidate) + candidate += 2 + raise ValueError("Не удалось подобрать e") + + def _compute_d(self) -> int: + k = 1 + while True: + if (k * self.phi + 1) % self.e.value == 0: + return (k * self.phi + 1) // self.e.value + k += 1 + + def make_public_key(self) -> PublicKey: + return PublicKey(self.e, self.n) + + def decrypt(self, c: int) -> int: + if not isinstance(c, int) or c < 0: + raise ValueError( + "Шифртекст c должен быть неотрицательным целым числом") + return pow(c, self.d, self.n) diff --git a/lab2-the-RSA-algorithm/app/core/public_key.py b/lab2-the-RSA-algorithm/app/core/public_key.py new file mode 100644 index 0000000..6e3720e --- /dev/null +++ b/lab2-the-RSA-algorithm/app/core/public_key.py @@ -0,0 +1,23 @@ +from .prime_number import PrimeNumber + + +class PublicKey: + """ + Публичный ключ (e, n). + e — экземпляр PrimeNumber (простое число). + n — целое (составное число p1*p2). + """ + + def __init__(self, e: PrimeNumber, n: int): + if not isinstance(e, PrimeNumber): + raise TypeError("e должно быть экземпляром PrimeNumber") + if not isinstance(n, int): + raise TypeError("n должно быть int (составное число)") + self.e = e + self.n = n + + def encrypt(self, m: int) -> int: + if not isinstance(m, int) or m < 0: + raise ValueError( + "Сообщение m должно быть неотрицательным целым числом") + return pow(m, self.e.value, self.n) diff --git a/lab2-the-RSA-algorithm/app/modes/auto.py b/lab2-the-RSA-algorithm/app/modes/auto.py new file mode 100644 index 0000000..a216e4a --- /dev/null +++ b/lab2-the-RSA-algorithm/app/modes/auto.py @@ -0,0 +1,68 @@ +from __future__ import annotations + +from typing import Dict, Any + +from modes.keygen import KeygenMode +from modes.encrypt import EncryptMode +from modes.decrypt import DecryptMode + + +class AutoMode: + """ + Автоматический режим: + 1. Генерация ключей (p, q, n, e, d, phi). + 2. Шифрование текста или числа. + 3. Расшифрование результата обратно. + """ + + def run( + self, + *, + text: str | None, + m: int | None, + p: int | None = None, + q: int | None = None, + min: int | None = None, + max: int | None = None, + bits: int | None = None, + seed: int | None = None, + ) -> Dict[str, Any]: + # 1. Генерация ключей + keygen = KeygenMode() + keys = keygen.run( + p=p, + q=q, + min=min, + max=max, + bits=bits, + seed=seed, + ) + + n = keys["n"]["dec"] + e = keys["e"]["dec"] + d = keys["d"]["dec"] + + # 2. Шифрование + encrypt = EncryptMode() + encrypted = encrypt.run( + text=text, + m=m, + n=n, + e=e, + ) + + # 3. Расшифрование + decrypt = DecryptMode() + # В зависимости от формата encrypted["output"] + if encrypted["mode"] == "text": + ciphers = [item["cipher"] for item in encrypted["output"]] + decrypted = decrypt.run(c=ciphers, n=n, d=d) + else: + cipher = encrypted["output"]["cipher"] + decrypted = decrypt.run(c=cipher, n=n, d=d) + + return { + "keys": keys, + "encrypted": encrypted, + "decrypted": decrypted, + } diff --git a/lab2-the-RSA-algorithm/app/modes/decrypt.py b/lab2-the-RSA-algorithm/app/modes/decrypt.py new file mode 100644 index 0000000..4ba00bc --- /dev/null +++ b/lab2-the-RSA-algorithm/app/modes/decrypt.py @@ -0,0 +1,55 @@ +# modes/decrypt.py +from __future__ import annotations + +from typing import Dict, Any, List + + +class DecryptMode: + def run( + self, + *, + c: int | List[int], + n: int, + d: int, + ) -> Dict[str, Any]: + # Один блок + if isinstance(c, int): + plain = pow(c, d, n) # Дешифратор + char = chr(plain) if 0 <= plain < 128 else None + return { + "mode": "int", + "input": { + "cipher": c, + "hex_in": hex(c), + }, + "output": { + "ascii": plain, + "char": char, + "hex_out": hex(plain), + }, + } + + # Несколько блоков (список чисел) + if isinstance(c, list): + result: List[Dict[str, Any]] = [] + text = "" + for block in c: + plain = pow(block, d, n) # Дешифратор + char = chr(plain) if 0 <= plain < 128 else None + if char: + text += char + result.append({ + "cipher": block, + "hex_in": hex(block), + "ascii": plain, + "char": char, + "hex_out": hex(plain), + }) + return { + "mode": "list", + "input": c, + "output": result, + "text": text, + } + + raise ValueError("c должен быть числом или списком чисел") diff --git a/lab2-the-RSA-algorithm/app/modes/encrypt.py b/lab2-the-RSA-algorithm/app/modes/encrypt.py new file mode 100644 index 0000000..658dd31 --- /dev/null +++ b/lab2-the-RSA-algorithm/app/modes/encrypt.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from typing import Dict, Any, List + +from core.public_key import PublicKey + +from core.prime_number import PrimeNumber + + +class EncryptMode: + def run( + self, + *, + text: str | None, + m: int | None, + n: int, + e: int, + ) -> Dict[str, Any]: + pub = PublicKey(n=n, e=PrimeNumber(e)) + + if text is not None: + result: List[Dict[str, Any]] = [] + for ch in text: + code = ord(ch) + cipher = pub.encrypt(code) + result.append({ + "char": ch, + "ascii": code, + "hex_in": hex(code), + "cipher": cipher, + "hex_out": hex(cipher), + }) + return { + "mode": "text", + "input": text, + "output": result, + } + + if m is not None: + cipher = pub.encrypt(m) + char = chr(m) if 0 <= m < 128 else None + return { + "mode": "int", + "input": { + "char": char, + "ascii": m, + "hex_in": hex(m), + }, + "output": { + "char": char, + "ascii": m, + "cipher": cipher, + "hex_out": hex(cipher), + }, + } + + raise ValueError("Необходимо указать либо text, либо m") diff --git a/lab2-the-RSA-algorithm/app/modes/keygen.py b/lab2-the-RSA-algorithm/app/modes/keygen.py new file mode 100644 index 0000000..b7f4024 --- /dev/null +++ b/lab2-the-RSA-algorithm/app/modes/keygen.py @@ -0,0 +1,133 @@ +from __future__ import annotations + +from typing import Dict, Any +from core.prime_number import PrimeNumber +from core.private_key import PrivateKey + + +class KeygenMode: + MAX_BITS: int = 2**5 + MIN_VALUE: int = 2 + MAX_VALUE: int = (1 << MAX_BITS) - 1 + MAX_ATTEMPTS: int = 1000 + + def run( + self, + *, + p: int | None, + q: int | None, + min: int | None = None, + max: int | None = None, + bits: int | None = None, + seed: int | None = None, + ) -> Dict[str, Any]: + + if min is None: + min = self.MIN_VALUE + if max is None: + max = self.MAX_VALUE + + self._validate_inputs(p, q, min, max, bits) + + P = self._generate_prime(p, min, max, bits, seed) + Q = self._generate_distinct_prime(P, q, min, max, bits, seed) + + priv = PrivateKey(P, Q) + pub = priv.make_public_key() + + return { + "p": { + "dec": P.value, + "hex": hex(P.value), + }, + "q": { + "dec": Q.value, + "hex": hex(Q.value), + }, + "n": { + "dec": priv.n, + "hex": hex(priv.n), + }, + "phi": { + "dec": priv.phi, + "hex": hex(priv.phi), + }, + "e": { + "dec": pub.e.value, + "hex": hex(pub.e.value), + }, + "d": { + "dec": priv.d, + "hex": hex(priv.d), + }, + } + + # ----------------- helpers ----------------- + + def _validate_inputs( + self, + p: int | None, + q: int | None, + min: int, + max: int, + bits: int | None, + ) -> None: + + if p is not None and q is not None and p == q: + raise ValueError("p и q должны быть разными простыми числами.") + + if bits is not None and bits > self.MAX_BITS: + raise ValueError(f"Максимальная длина простого: { + self.MAX_BITS} бит.") + if min > max: + raise ValueError("min не может быть больше max.") + if max > self.MAX_VALUE: + raise ValueError( + f"max не может превышать {self.MAX_VALUE} (ограничение { + self.MAX_BITS} бит)." + ) + if min == max: + raise ValueError("min и max не должны совпадать.") + + def _generate_prime( + self, + value: int | None, + min: int, + max: int, + bits: int | None, + seed: int | None, + ) -> PrimeNumber: + if value is not None: + return PrimeNumber.from_value(value) + if bits is not None: + return PrimeNumber.random_bits(bits=bits, seed=seed) + else: + return PrimeNumber.random(min_value=min, max_value=max, seed=seed) + return PrimeNumber.random_bits(bits=self.MAX_BITS, seed=seed) + + def _generate_distinct_prime( + self, + other: PrimeNumber, + value: int | None, + min: int, + max: int, + bits: int | None, + seed: int | None, + ) -> PrimeNumber: + attempts = 0 + + while True: + + effective_seed = None if seed is None else seed + attempts + + candidate = self._generate_prime( + value, min, max, bits, effective_seed) + if candidate.value != other.value: + return candidate + + attempts += 1 + if attempts >= self.MAX_ATTEMPTS: + raise RuntimeError( + f"Не удалось сгенерировать q, отличное от p, за { + self.MAX_ATTEMPTS} попыток." + ) diff --git a/lab2-the-RSA-algorithm/app/tests/__init__.py b/lab2-the-RSA-algorithm/app/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lab2-the-RSA-algorithm/app/tests/test_prime_number.py b/lab2-the-RSA-algorithm/app/tests/test_prime_number.py new file mode 100644 index 0000000..6653e4e --- /dev/null +++ b/lab2-the-RSA-algorithm/app/tests/test_prime_number.py @@ -0,0 +1,26 @@ +import pytest +from core.prime_number import PrimeNumber + + +def test_from_value_valid(): + p = PrimeNumber.from_value(61) + assert p.value == 61 + assert repr(p) == "PrimeNumber(61)" + + +def test_from_value_invalid(): + with pytest.raises(ValueError): + PrimeNumber.from_value(60) # не простое + + +def test_random_in_range(): + p = PrimeNumber.random(2, 20) + assert isinstance(p, PrimeNumber) + assert 2 <= p.value <= 20 + # дополнительно проверим, что оно действительно простое + assert PrimeNumber._is_prime(p.value) + + +def test_random_no_primes(): + with pytest.raises(ValueError): + PrimeNumber.random(90, 92) # в этом диапазоне простых нет diff --git a/lab2-the-RSA-algorithm/app/tests/test_private_key.py b/lab2-the-RSA-algorithm/app/tests/test_private_key.py new file mode 100644 index 0000000..48eaee8 --- /dev/null +++ b/lab2-the-RSA-algorithm/app/tests/test_private_key.py @@ -0,0 +1,50 @@ +import pytest +from core.private_key import PrivateKey +from core.prime_number import PrimeNumber + + +def test_encrypt_decrypt_cycle(): + """Проверка: сообщение после encrypt → decrypt восстанавливается""" + p1 = PrimeNumber.from_value(61) + p2 = PrimeNumber.from_value(53) + priv = PrivateKey(p1, p2) + pub = priv.make_public_key() + + messages = [1, 2, 42, 123, priv.n - 1] + for m in messages: + c = pub.encrypt(m) + m_back = priv.decrypt(c) + assert m == m_back + + +def test_e_is_prime_and_coprime_with_phi(): + """e должно быть простым и взаимно простым с φ(n)""" + p1 = PrimeNumber.from_value(61) + p2 = PrimeNumber.from_value(53) + priv = PrivateKey(p1, p2) + + assert isinstance(priv.e, PrimeNumber) + assert (priv.e.value > 1) + assert (priv.phi % priv.e.value != 0) + + +def test_d_is_inverse_of_e_mod_phi(): + """e*d ≡ 1 (mod φ(n))""" + p1 = PrimeNumber.from_value(61) + p2 = PrimeNumber.from_value(53) + priv = PrivateKey(p1, p2) + + assert (priv.e.value * priv.d) % priv.phi == 1 + + +def test_decrypt_invalid_inputs(): + """Должны бросаться ошибки при неверных входных данных""" + p1 = PrimeNumber.from_value(61) + p2 = PrimeNumber.from_value(53) + priv = PrivateKey(p1, p2) + + with pytest.raises(ValueError): + priv.decrypt(-5) + + with pytest.raises(ValueError): + priv.decrypt("not a number") # type: ignore diff --git a/lab2-the-RSA-algorithm/app/tests/test_public_key.py b/lab2-the-RSA-algorithm/app/tests/test_public_key.py new file mode 100644 index 0000000..c68ded2 --- /dev/null +++ b/lab2-the-RSA-algorithm/app/tests/test_public_key.py @@ -0,0 +1,47 @@ +import pytest +from core.prime_number import PrimeNumber +from core.public_key import PublicKey + + +def test_encrypt_basic_cycle(): + """Шифрование совпадает с pow(m, e, n)""" + e = PrimeNumber.from_value(3) + n = 11 # n может быть простым или составным числом + pub = PublicKey(e, n) + + for m in range(1, 10): + expected = pow(m, e.value, n) + assert pub.encrypt(m) == expected + + +def test_encrypt_with_composite_n(): + """n = p1 * p2 должно работать корректно""" + p1 = PrimeNumber.from_value(5) + p2 = PrimeNumber.from_value(11) + n = p1.value * p2.value + e = PrimeNumber.from_value(3) + + pub = PublicKey(e, n) + m = 7 + expected = pow(m, e.value, n) + assert pub.encrypt(m) == expected + + +def test_encrypt_rejects_negative(): + """Отрицательные сообщения запрещены""" + e = PrimeNumber.from_value(3) + n = 11 + pub = PublicKey(e, n) + + with pytest.raises(ValueError): + pub.encrypt(-1) + + +def test_encrypt_rejects_non_integer(): + """Сообщение должно быть int""" + e = PrimeNumber.from_value(3) + n = 11 + pub = PublicKey(e, n) + + with pytest.raises(ValueError): + pub.encrypt(3.14) diff --git a/lab2-the-RSA-algorithm/lab2_the_RSA_algorithm.docx b/lab2-the-RSA-algorithm/lab2_the_RSA_algorithm.docx new file mode 100644 index 0000000000000000000000000000000000000000..144b3b89b4870e3865dde2888ba684fd900cb457 GIT binary patch literal 18094 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 literal 0 HcmV?d00001 diff --git a/lab3-hash-function/app/app.py b/lab3-hash-function/app/app.py new file mode 100644 index 0000000..2ff3584 --- /dev/null +++ b/lab3-hash-function/app/app.py @@ -0,0 +1,68 @@ +import json +import sys + +from cli.parse_args import parse_args + + +def main() -> int: + args = parse_args() + + try: + if args.cmd == "hash": + from modes.hash_mode import HashMode + runner = HashMode() + result = runner.run( + variant=args.variant, + message=args.message, + salt=args.salt, + bytes=args.bytes, + ) + + elif args.cmd == "avalanche": + from modes.test_avalanche import AvalancheTest + runner = AvalancheTest() + result = runner.run( + variant=args.variant, + message=args.message, + salt=args.salt, + bytes=args.bytes, + ) + + elif args.cmd == "collisions": + from modes.test_collisions import CollisionsTest + runner = CollisionsTest() + result = runner.run( + variant=args.variant, + max_len=args.max_len, + alphabet=args.alphabet, + bytes=args.bytes, + ) + + elif args.cmd == "analyze": + from modes.analyze_uniformity import UniformityAnalyzer + runner = UniformityAnalyzer() + result = runner.run( + variant=args.variant, + count=args.count, + buckets=args.buckets, + ) + + else: + raise RuntimeError(f"Неизвестная команда: {args.cmd}") + + # Печать результата + if result is not None: + if isinstance(result, (dict, list)): + print(json.dumps(result, ensure_ascii=False, indent=2)) + else: + print(result) + + return 0 + + except Exception as exc: + print(f"Ошибка: {exc}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + main() diff --git a/lab3-hash-function/app/cli/parse_args.py b/lab3-hash-function/app/cli/parse_args.py new file mode 100644 index 0000000..e98e305 --- /dev/null +++ b/lab3-hash-function/app/cli/parse_args.py @@ -0,0 +1,53 @@ +from argparse import ArgumentParser + + +def parse_args(argv=None): + ap = ArgumentParser( + prog="app.py", + description="CLI для лабораторной по хэшированию" + ) + + sub = ap.add_subparsers(dest="cmd", required=True) + + # --- Общие группы --- + common_variant = ArgumentParser(add_help=False) + common_variant.add_argument("-v", "--variant", choices=["1", "2", "3"], required=True, + help="Выбор варианта: 1=sin, 2=cos, 3=xor") + + common_salt = ArgumentParser(add_help=False) + common_salt.add_argument("-s", "--salt", type=str, default="", + help="Соль (по умолчанию пустая)") + + common_bytes = ArgumentParser(add_help=False) + common_bytes.add_argument("--bytes", type=int, default=16, + help="Количество значимых байтов хэша (по умолчанию 16)") + + # --- HASH --- + sp_hash = sub.add_parser("hash", parents=[common_variant, common_salt, common_bytes], + help="Посчитать хэш сообщения") + sp_hash.add_argument("-m", "--message", type=str, default="", + help="Сообщение (может быть пустым)") + + # --- AVALANCHE --- + sp_av = sub.add_parser("avalanche", parents=[common_variant, common_salt, common_bytes], + help="Тест эффекта лавины") + sp_av.add_argument("-m", "--message", type=str, required=True, + help="Базовое сообщение") + + # --- COLLISIONS --- + sp_col = sub.add_parser("collisions", parents=[common_variant, common_bytes], + help="Поиск коллизий (перебор)") + sp_col.add_argument("--max-len", type=int, default=3, + help="Максимальная длина сообщений (по умолчанию 3)") + sp_col.add_argument("--alphabet", choices=["alnum", "alpha", "digits"], default="alnum", + help="Алфавит: alnum[a-z0-9], alpha[a-z], digits[0-9]") + + # --- ANALYZE --- + sp_an = sub.add_parser("analyze", parents=[common_variant, common_bytes], + help="Анализ равномерности") + sp_an.add_argument("--count", type=int, default=100, + help="Сколько сообщений сгенерировать") + sp_an.add_argument("--buckets", type=int, default=10, + help="Сколько корзин для распределения (по умолчанию 10)") + + return ap.parse_args(argv) diff --git a/lab3-hash-function/app/modes/analyze_uniformity.py b/lab3-hash-function/app/modes/analyze_uniformity.py new file mode 100644 index 0000000..6753813 --- /dev/null +++ b/lab3-hash-function/app/modes/analyze_uniformity.py @@ -0,0 +1,44 @@ +import string +import random +from modes.hash_mode import HashMode + + +class UniformityAnalyzer: + """ + Анализ равномерности распределения хэшей. + """ + + def run(self, variant: str, count: int = 100, buckets: int = 10, bytes: int = 16) -> dict: + hasher = HashMode() + alphabet = string.ascii_lowercase + string.digits + + # случайные сообщения + messages = [ + "".join(random.choice(alphabet) + for _ in range(random.randint(5, 10))) + for _ in range(count) + ] + + # хэши + hashes = [hasher.run(variant, msg, bytes=bytes) for msg in messages] + + # берём первые 8 hex-символов → число + values = [int(h[:8], 16) for h in hashes] + values.sort() + + # диапазоны + min_val, max_val = values[0], values[-1] + step = (max_val - min_val) / buckets if max_val > min_val else 1 + + distribution = [0] * buckets + for v in values: + idx = min(int((v - min_val) / step), buckets - 1) + distribution[idx] += 1 + + return { + "count": count, + "buckets": buckets, + "messages": messages, + "hashes": hashes, + "distribution": distribution, + } diff --git a/lab3-hash-function/app/modes/hash_mode.py b/lab3-hash-function/app/modes/hash_mode.py new file mode 100644 index 0000000..ad8b63b --- /dev/null +++ b/lab3-hash-function/app/modes/hash_mode.py @@ -0,0 +1,95 @@ +# modes/hash_mode.py +import math + + +class HashMode: + """ + Учебная хэш-функция. + Варианты: + 1 = sin-based + 2 = cos-based + 3 = xor-based + """ + + def run(self, variant: str, message: str, salt: str = "", bytes: int = 16) -> str: + if not (2 <= bytes <= 16): + raise ValueError("Параметр bytes должен быть в диапазоне [2, 16]") + + data = (message + salt).encode("utf-8") + + if variant == "1": + out = self._sin_hash(data) + elif variant == "2": + out = self._cos_hash(data) + elif variant == "3": + out = self._xor_hash(data) + else: + raise ValueError(f"Неизвестный вариант: {variant}") + + # Обрезаем до нужного числа байт + truncated = self._truncate_bytes(out, bytes) + return ''.join(f"{x:02x}" for x in truncated) + + # --- служебные ------------------------------------------------------ + + def _truncate_bytes(self, out: bytearray, bytes: int) -> bytearray: + if bytes >= len(out): + return out + truncated = out[:bytes] + # примешиваем все отброшенные байты в оставшиеся + for i, b in enumerate(out[bytes:], start=1): + truncated[i % len(truncated)] ^= b + return truncated + + # --- реализации ------------------------------------------------------ + + def _sin_hash(self, data: bytes) -> bytearray: + out = [0x55 ^ i for i in range(16)] + if not data: + return out + + angle = (2 * math.pi) / (len(out) * len(data)) + + for i, b in enumerate(data, 1): + for j in range(len(out)): + val = int((math.sin(b + (i + j) * angle) + 1) * 127) + out[j] ^= val & 0xFF + + return out + + def _cos_hash(self, data: bytes) -> bytearray: + out = [0x77 ^ i for i in range(16)] + if not data: + return out + + angle = (2 * math.pi) / (len(out) * len(data)) + + for i, b in enumerate(data, 1): + for j in range(len(out)): + val = int((math.cos(b + (i + j) * angle) + 1) * 127) + out[j] ^= val & 0xFF + + return out + + def _mix_bits(self, mix: int) -> bytearray: + # количество байт у числа = (битовая длина + 7) // 8 + count = (mix.bit_length() + 7) // 8 + for i in range(1, count): + mix ^= (mix >> (8 * i)) + + return mix + + def _xor_hash(self, data: bytes) -> bytearray: + out = [0xAA ^ i for i in range(16)] + if not data: + return out + + phi = (1 + 5 ** 0.5) / 2 # золотое сечение + + for i, b in enumerate(data, 1): + for j in range(16): + mix = (b * (i + j + 1)) ^ int(phi * 1e6) + mix = self._mix_bits(mix) + out[j] ^= mix & 0xFF # только младший байт + + return out diff --git a/lab3-hash-function/app/modes/test_avalanche.py b/lab3-hash-function/app/modes/test_avalanche.py new file mode 100644 index 0000000..d7c5abe --- /dev/null +++ b/lab3-hash-function/app/modes/test_avalanche.py @@ -0,0 +1,39 @@ +from modes.hash_mode import HashMode + + +class AvalancheTest: + """ + Проверка эффекта лавины: + небольшое изменение во входном сообщении должно сильно менять хэш. + """ + + def run(self, variant: str, message: str, salt: str = "", bytes: int = 16) -> dict: + hasher = HashMode() + + # базовый хэш + h1 = hasher.run(variant, message, salt=salt, bytes=bytes) + + # изменяем один символ (если пусто — подставим "a") + if message: + i = 0 # всегда первый символ для простоты + flipped_char = chr((ord(message[i]) + 1) % 128) + mod_msg = flipped_char + message[1:] + else: + mod_msg = "a" + + h2 = hasher.run(variant, mod_msg, salt=salt, bytes=bytes) + + # сравнение побитово + diff_bits = sum(c1 != c2 for c1, c2 in zip( + bin(int(h1, 16))[2:], bin(int(h2, 16))[2:])) + total_bits = len(h1) * 4 # HEX -> биты + + return { + "original": message, + "modified": mod_msg, + "hash1": h1, + "hash2": h2, + "diff_bits": diff_bits, + "total_bits": total_bits, + "diff_percent": round(100 * diff_bits / total_bits, 2), + } diff --git a/lab3-hash-function/app/modes/test_collisions.py b/lab3-hash-function/app/modes/test_collisions.py new file mode 100644 index 0000000..a9f5271 --- /dev/null +++ b/lab3-hash-function/app/modes/test_collisions.py @@ -0,0 +1,38 @@ +import itertools +import string +from modes.hash_mode import HashMode + + +class CollisionsTest: + """ + Грубый поиск коллизий: перебираем строки до max_len + из заданного алфавита и проверяем, совпадут ли хэши. + """ + + def run(self, variant: str, max_len: int = 3, alphabet: str = "alnum", bytes: int = 16) -> dict: + hasher = HashMode() + seen = {} + + # выбор алфавита + if alphabet == "alnum": + chars = string.ascii_lowercase + string.digits + elif alphabet == "alpha": + chars = string.ascii_lowercase + elif alphabet == "digits": + chars = string.digits + else: + raise ValueError(f"Неизвестный алфавит: {alphabet}") + + for length in range(1, max_len + 1): + for msg_tuple in itertools.product(chars, repeat=length): + msg = "".join(msg_tuple) + h = hasher.run(variant, msg, bytes=bytes) + if h in seen: + return { + "collision_found": True, + "hash": h, + "messages": [seen[h], msg], + } + seen[h] = msg + + return {"collision_found": False} diff --git a/lab3-hash-function/lab3_hash_function.docx b/lab3-hash-function/lab3_hash_function.docx new file mode 100644 index 0000000000000000000000000000000000000000..1d8b6ae5bcb1a367176cbf713cfe401202201285 GIT binary patch literal 18459 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 UKj`-W*v}8pr-gzF|MBnt1HXrwR{#J2 literal 0 HcmV?d00001 diff --git a/lab4-electronic-digital-signature/app/app.py b/lab4-electronic-digital-signature/app/app.py new file mode 100644 index 0000000..6f84f53 --- /dev/null +++ b/lab4-electronic-digital-signature/app/app.py @@ -0,0 +1,89 @@ +import subprocess +import json +import sys +from pathlib import Path +from cli.parse_args import parse_args + +LAB2 = Path(__file__).resolve().parents[2] / \ + "lab2-the-RSA-algorithm" / "app" / "app.py" +LAB3 = Path(__file__).resolve().parents[2] / \ + "lab3-hash-function" / "app" / "app.py" + + +def run_lab2_keygen(bits: int, seed: int | None): + cmd = [sys.executable, str(LAB2), "keygen", "--bits", str(bits)] + if seed is not None: + cmd += ["--seed", str(seed)] + res = subprocess.run(cmd, capture_output=True, text=True, check=True) + return json.loads(res.stdout) + + +def run_lab3_hash(variant: str, text: str, bytes_len: int): + cmd = [ + sys.executable, + str(LAB3), + "hash", + "-v", + variant, + "-m", + text, + "--bytes", + str(bytes_len), + ] + res = subprocess.run(cmd, capture_output=True, text=True, check=True) + return res.stdout.strip() # ожидается hex-строка + + +def main(): + args = parse_args() + + # Фиксированные параметры RSA и HASH + bits = 32 + bytes_len = 7 + + # 1. Генерация ключей RSA + keys = run_lab2_keygen(bits, args.seed) + n = int(keys["n"]["dec"]) + e = int(keys["e"]["dec"]) + d = int(keys["d"]["dec"]) + + print("RSA ключи сгенерированы:") + print(json.dumps(keys, indent=2, ensure_ascii=False)) + + # 2. Хэш исходного текста + h_hex = run_lab3_hash(args.variant, args.text, bytes_len) + h = int(h_hex, 16) + print(f"\nХэш исходного сообщения: {h_hex} (dec={h})") + + # 3. Проверка условия n > h + if h >= n: + print( + "\n[ОШИБКА] Хэш больше или равен n. Нужно пересоздать ключи с большим размером.") + sys.exit(1) + + # 4. Подпись: S = h^d mod n + S = pow(h, d, n) + print(f"\nПодпись (S): {S}") + + # 5. Проверка подписи для исходного сообщения + h_check = pow(S, e, n) + print(f"Проверка подписи: {h_check} == {h} ? { + 'OK' if h_check == h else 'FAIL'}") + + # 6. Если передан модифицированный текст — проверить и его + if args.tampered: + h_tampered_hex = run_lab3_hash(args.variant, args.tampered, bytes_len) + h_tampered = int(h_tampered_hex, 16) + print(f"\nХэш модифицированного сообщения: { + h_tampered_hex} (dec={h_tampered})") + + h_check_tampered = pow(S, e, n) + print( + f"Проверка подписи для модифицированного текста: " + f"{h_check_tampered} == {h_tampered} ? { + 'OK' if h_check_tampered == h_tampered else 'FAIL'}" + ) + + +if __name__ == "__main__": + main() diff --git a/lab4-electronic-digital-signature/app/cli/parse_args.py b/lab4-electronic-digital-signature/app/cli/parse_args.py new file mode 100644 index 0000000..1037bd6 --- /dev/null +++ b/lab4-electronic-digital-signature/app/cli/parse_args.py @@ -0,0 +1,25 @@ +from argparse import ArgumentParser + + +def parse_args(argv=None): + ap = ArgumentParser( + prog="app.py", + description="ЭЦП (RSA + собственная хэш-функция). " + "Выполняет полный цикл: генерация ключей, подпись и проверку." + ) + + # --- RSA --- + ap.add_argument("-s", "--seed", type=int, + help="Seed для ГСЧ (опционально, для воспроизводимости).") + + # --- HASH --- + ap.add_argument("-v", "--variant", choices=["1", "2", "3"], required=True, + help="Вариант хэш-функции (см. lab3).") + + # --- MESSAGES --- + ap.add_argument("-t", "--text", type=str, required=True, + help="Исходное сообщение (ASCII).") + ap.add_argument("-m", "--tampered", type=str, + help="Модифицированное сообщение для имитации нарушения целостности.") + + return ap.parse_args(argv) diff --git a/lab4-electronic-digital-signature/lab4_electronic_digital_signature.docx b/lab4-electronic-digital-signature/lab4_electronic_digital_signature.docx new file mode 100644 index 0000000000000000000000000000000000000000..7db0f57e108146302fe4e31e3646eb7d0c36569b GIT binary patch literal 17979 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 I{c-gF0QhBr`v3p{ literal 0 HcmV?d00001 diff --git a/lab5-account-manager-security/app.py b/lab5-account-manager-security/app.py new file mode 100644 index 0000000..b3d9fc6 --- /dev/null +++ b/lab5-account-manager-security/app.py @@ -0,0 +1,34 @@ +from core import PasswordHasher, IntegrityChecker, CryptoManager, AuditLogger, AccountManager +from gui import MainWindow + + +class App: + """ + Класс точки входа для запуска менеджера учётных записей. + """ + + def __init__(self): + self.db_file = None + self.hash_file = "data/accounts.db.hash" + self.log_file = "data/audit.log" + + self.password_hasher = PasswordHasher() + self.integrity_checker = IntegrityChecker() + self.crypto_manager = CryptoManager() + self.audit_logger = AuditLogger(self.log_file) + self.account_manager = AccountManager(self.db_file) + + self.gui = MainWindow( + account_manager=self.account_manager, + password_hasher=self.password_hasher, + audit_logger=self.audit_logger, + crypto_manager=self.crypto_manager, + integrity_checker=self.integrity_checker, + ) + + def run(self): + self.gui.run() + + +if __name__ == "__main__": + App().run() diff --git a/lab5-account-manager-security/core/__init__.py b/lab5-account-manager-security/core/__init__.py new file mode 100644 index 0000000..1cc1494 --- /dev/null +++ b/lab5-account-manager-security/core/__init__.py @@ -0,0 +1,5 @@ +from .password_hasher import PasswordHasher +from .integrity_checker import IntegrityChecker +from .crypto_manager import CryptoManager +from .audit_logger import AuditLogger +from .account_manager import AccountManager diff --git a/lab5-account-manager-security/core/account_manager.py b/lab5-account-manager-security/core/account_manager.py new file mode 100644 index 0000000..a5f04c9 --- /dev/null +++ b/lab5-account-manager-security/core/account_manager.py @@ -0,0 +1,62 @@ +import json +from pathlib import Path + + +class AccountManager: + """ + Класс для управления учётными записями пользователей. + """ + + def __init__(self, db_file: str | None): + self.db_file = Path(db_file) if db_file else None + if isinstance(self.db_file, Path) and not self.db_file.exists(): + self._save_db({}) + + def set_db_file(self, db_file: str | None) -> None: + self.db_file = Path(db_file) if db_file else None + if isinstance(self.db_file, Path) and not self.db_file.exists(): + self._save_db({}) + + def _load_db(self) -> dict: + if not isinstance(self.db_file, Path): + return {} + if self.db_file.exists(): + return json.loads(self.db_file.read_text(encoding="utf-8")) + return {} + + def _save_db(self, data: dict) -> None: + if not isinstance(self.db_file, Path): + raise RuntimeError("База данных не открыта") + self.db_file.write_text(json.dumps( + data, indent=2, ensure_ascii=False), encoding="utf-8") + + def add_user(self, username: str, password_hash: str, salt: str) -> None: + data = self._load_db() + data[username] = {"hash": password_hash, "salt": salt} + self._save_db(data) + + def update_user(self, username: str, password_hash: str, salt: str) -> bool: + data = self._load_db() + if username not in data: + return False + data[username] = {"hash": password_hash, "salt": salt} + self._save_db(data) + return True + + def delete_user(self, username: str) -> bool: + data = self._load_db() + if username not in data: + return False + del data[username] + self._save_db(data) + return True + + def get_user(self, username: str) -> dict | None: + data = self._load_db() + return data.get(username) + + def list_users(self) -> list[str]: + if not isinstance(self.db_file, Path): + return [] + data = self._load_db() + return list(data.keys()) diff --git a/lab5-account-manager-security/core/audit_logger.py b/lab5-account-manager-security/core/audit_logger.py new file mode 100644 index 0000000..7f2b1a1 --- /dev/null +++ b/lab5-account-manager-security/core/audit_logger.py @@ -0,0 +1,17 @@ +from datetime import datetime +from pathlib import Path + + +class AuditLogger: + """ + Класс для ведения журнала событий. + """ + + def __init__(self, log_file: str): + self.log_file = Path(log_file) + + def log(self, event: str) -> None: + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + line = f"[{timestamp}] {event}\n" + with open(self.log_file, "a", encoding="utf-8") as f: + f.write(line) diff --git a/lab5-account-manager-security/core/crypto_manager.py b/lab5-account-manager-security/core/crypto_manager.py new file mode 100644 index 0000000..11b6d07 --- /dev/null +++ b/lab5-account-manager-security/core/crypto_manager.py @@ -0,0 +1,23 @@ +from cryptography.fernet import Fernet +from pathlib import Path + + +class CryptoManager: + """ + Класс для симметричного шифрования и расшифрования файлов. + """ + + def generate_key(self) -> bytes: + return Fernet.generate_key() + + def encrypt_file(self, file_path: str, key: bytes, output_path: str) -> None: + fernet = Fernet(key) + data = Path(file_path).read_bytes() + encrypted = fernet.encrypt(data) + Path(output_path).write_bytes(encrypted) + + def decrypt_file(self, file_path: str, key: bytes, output_path: str) -> None: + fernet = Fernet(key) + data = Path(file_path).read_bytes() + decrypted = fernet.decrypt(data) + Path(output_path).write_bytes(decrypted) diff --git a/lab5-account-manager-security/core/integrity_checker.py b/lab5-account-manager-security/core/integrity_checker.py new file mode 100644 index 0000000..a0c196f --- /dev/null +++ b/lab5-account-manager-security/core/integrity_checker.py @@ -0,0 +1,26 @@ +import hashlib +from pathlib import Path + + +class IntegrityChecker: + """ + Класс для проверки целостности файлов по хэш-сумме. + """ + + def calculate_hash(self, file_path: str) -> str: + hasher = hashlib.sha256() + with open(file_path, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hasher.update(chunk) + return hasher.hexdigest() + + def save_hash(self, file_path: str, hash_file: str) -> None: + file_hash = self.calculate_hash(file_path) + Path(hash_file).write_text(file_hash, encoding="utf-8") + + def verify_hash(self, file_path: str, hash_file: str) -> bool: + if not Path(hash_file).exists(): + return False + expected = Path(hash_file).read_text(encoding="utf-8").strip() + actual = self.calculate_hash(file_path) + return expected == actual diff --git a/lab5-account-manager-security/core/password_hasher.py b/lab5-account-manager-security/core/password_hasher.py new file mode 100644 index 0000000..c395555 --- /dev/null +++ b/lab5-account-manager-security/core/password_hasher.py @@ -0,0 +1,19 @@ +import hashlib +import secrets + + +class PasswordHasher: + """ + Класс для безопасного хэширования паролей с использованием соли. + """ + + def generate_salt(self, length: int = 16) -> str: + return secrets.token_hex(length) + + def hash_password(self, password: str, salt: str) -> str: + hasher = hashlib.sha256() + hasher.update(salt.encode("utf-8") + password.encode("utf-8")) + return hasher.hexdigest() + + def verify_password(self, password: str, salt: str, expected_hash: str) -> bool: + return self.hash_password(password, salt) == expected_hash diff --git a/lab5-account-manager-security/data/accounts.db b/lab5-account-manager-security/data/accounts.db new file mode 100644 index 0000000..c6a19d0 --- /dev/null +++ b/lab5-account-manager-security/data/accounts.db @@ -0,0 +1,6 @@ +{ + "user2": { + "hash": "4d3596717c7887c07c607485fa8c287547a5e65559b3269844261417b1e7a97b", + "salt": "a1bb56a86e8d504634668696d9e65189" + } +} \ No newline at end of file diff --git a/lab5-account-manager-security/data/accounts.db.hash b/lab5-account-manager-security/data/accounts.db.hash new file mode 100644 index 0000000..69715a8 --- /dev/null +++ b/lab5-account-manager-security/data/accounts.db.hash @@ -0,0 +1 @@ +109fb5ce85641ad0ed60cf8ae800289517d33c2cb100f39e5c7c74cb88b9b722 \ No newline at end of file diff --git a/lab5-account-manager-security/data/audit.log.dec b/lab5-account-manager-security/data/audit.log.dec new file mode 100644 index 0000000..56bd1c2 --- /dev/null +++ b/lab5-account-manager-security/data/audit.log.dec @@ -0,0 +1,3 @@ +[2025-10-01 21:51:42] Добавлен пользователь: user +[2025-10-01 21:51:48] Добавлен пользователь: user2 +[2025-10-01 21:51:55] Добавлен пользователь: user3 diff --git a/lab5-account-manager-security/data/audit.log.enc b/lab5-account-manager-security/data/audit.log.enc new file mode 100644 index 0000000..9841c5c --- /dev/null +++ b/lab5-account-manager-security/data/audit.log.enc @@ -0,0 +1 @@ +gAAAAABo3Wp_Jc6ye1Yf6rYq3GQ64_S6XHAQjm7WSCvS6fK48kMk5NmP7zFyX5AGShawV7uvFEVvx2v5Efn_hFWdML4I_iAf1x6jZheZLJuWzMLtsm4x25wEAo7c8vokR8YV-MaiJWKw_c9kdAzPoPpkfuZSAuwSU6hD_oNHooG8SPCWVTbbvmqwnquMchLpXaK_gfyYOgye_ERB5s5GBxMICwM47W87tGoKnFL6jtyGk8iIowPYD0xlrAhUwvuTeDfxlIhyOZBc72R5iTmiSbOgxNu6DyJy9-49kdSau35LTVWRThg7MEWxK1xTC5P6stXkhovNsjujsdcSBk8Rx-AgKBmSRPGznkC7zYTNw6gQhYujsi_WtaQ= \ No newline at end of file diff --git a/lab5-account-manager-security/data/encryption.key b/lab5-account-manager-security/data/encryption.key new file mode 100644 index 0000000..3e0827c --- /dev/null +++ b/lab5-account-manager-security/data/encryption.key @@ -0,0 +1 @@ +ir7gZ6qT1gP-wAcNvKB3Ua_k7zJ52bH_GmgdSO9iryo= \ No newline at end of file diff --git a/lab5-account-manager-security/gui/__init__.py b/lab5-account-manager-security/gui/__init__.py new file mode 100644 index 0000000..20afd67 --- /dev/null +++ b/lab5-account-manager-security/gui/__init__.py @@ -0,0 +1,3 @@ +from .main_window import MainWindow + +__all__ = ["MainWindow"] diff --git a/lab5-account-manager-security/gui/controls_panel.py b/lab5-account-manager-security/gui/controls_panel.py new file mode 100644 index 0000000..388b992 --- /dev/null +++ b/lab5-account-manager-security/gui/controls_panel.py @@ -0,0 +1,16 @@ +import tkinter as tk + + +class ControlsPanel: + """ + Панель управления действиями над пользователями. + """ + + def __init__(self, master, on_add, on_update, on_delete): + self.frame = tk.Frame(master) + tk.Button(self.frame, text="Добавить", + command=on_add).pack(side=tk.LEFT, padx=5) + tk.Button(self.frame, text="Изменить", + command=on_update).pack(side=tk.LEFT, padx=5) + tk.Button(self.frame, text="Удалить", command=on_delete).pack( + side=tk.LEFT, padx=5) diff --git a/lab5-account-manager-security/gui/crypto_tools.py b/lab5-account-manager-security/gui/crypto_tools.py new file mode 100644 index 0000000..9733fca --- /dev/null +++ b/lab5-account-manager-security/gui/crypto_tools.py @@ -0,0 +1,92 @@ +from __future__ import annotations + +from pathlib import Path +from tkinter import messagebox, filedialog as fd + + +class CryptoTools: + """Операции шифрования и расшифрования файлов.""" + + def __init__(self, crypto_manager, audit_logger): + self.crypto_manager = crypto_manager + self.audit_logger = audit_logger + + def _generate_and_save_key(self) -> bytes | None: + key = self.crypto_manager.generate_key() + path = fd.asksaveasfilename( + title="Сохранить ключ шифрования", + defaultextension=".key", + filetypes=[("Key file", "*.key"), ("All files", "*.*")], + initialfile="encryption.key", + ) + if not path: + return None + try: + Path(path).write_bytes(key) + except Exception as e: + messagebox.showerror("Сохранение ключа", + f"Не удалось сохранить ключ:\n{e}") + return None + messagebox.showinfo("Ключ сохранён", f"Ключ сохранён в:\n{path}") + return key + + def _load_key_from_file(self) -> bytes | None: + path = fd.askopenfilename( + title="Выберите файл ключа", + filetypes=[("Key file", "*.key"), ("All files", "*.*")], + ) + if not path: + return None + try: + return Path(path).read_bytes() + except Exception as e: + messagebox.showerror( + "Чтение ключа", f"Не удалось прочитать ключ:\n{e}") + return None + + def _select_output_path(self, suggested: Path, title: str, defext: str, pattern: str) -> Path | None: + path = fd.asksaveasfilename( + title=title, + defaultextension=defext, + filetypes=[(f"*{defext}", pattern), ("All files", "*.*")], + initialdir=str(suggested.parent), + initialfile=suggested.name, + ) + return Path(path) if path else None + + def encrypt_file(self): + src = fd.askopenfilename(title="Выберите файл для шифрования") + if not src: + return + key = self._generate_and_save_key() + if key is None: + return + suggested = Path(src).with_suffix(Path(src).suffix + ".enc") + out = self._select_output_path( + suggested, "Сохранить зашифрованный файл", ".enc", "*.enc") + if out is None: + return + self.crypto_manager.encrypt_file(src, key, str(out)) + self.audit_logger.log(f"Зашифрован файл → {out.name}") + messagebox.showinfo("Шифрование файла", f"Создан файл: {out}") + + def decrypt_file(self): + enc = fd.askopenfilename(title="Выберите зашифрованный файл", filetypes=[ + ("Encrypted", "*.enc"), ("All files", "*.*")]) + if not enc: + return + key = self._load_key_from_file() + if key is None: + return + suggested = Path(enc).with_suffix(".dec") + out = self._select_output_path( + suggested, "Сохранить расшифрованный файл", ".dec", "*.dec") + if out is None: + return + try: + self.crypto_manager.decrypt_file(enc, key, str(out)) + except Exception as e: + messagebox.showerror("Расшифрование файла", f"Ошибка:\n{e}") + return + self.audit_logger.log(f"Расшифрован файл → {out.name}") + messagebox.showinfo("Расшифрование файла", f"Создан файл: {out}") diff --git a/lab5-account-manager-security/gui/integrity_tools.py b/lab5-account-manager-security/gui/integrity_tools.py new file mode 100644 index 0000000..aeb1fab --- /dev/null +++ b/lab5-account-manager-security/gui/integrity_tools.py @@ -0,0 +1,73 @@ +from __future__ import annotations + +from pathlib import Path +from tkinter import messagebox, filedialog as fd + + +class IntegrityTools: + """Операции сохранения и проверки хэша БД.""" + + def __init__(self, integrity_checker, audit_logger, db_path: str | None): + self.integrity_checker = integrity_checker + self.audit_logger = audit_logger + self.db_path = Path(db_path) if db_path else None + + def set_db_path(self, db_path: str | None) -> None: + self.db_path = Path(db_path) if db_path else None + + def _hash_path(self) -> Path: + return self.db_path.with_suffix(self.db_path.suffix + ".hash") + + def save_db_hash(self): + if not self.db_path: + messagebox.showwarning("Сохранить хэш", "База данных не выбрана.") + return + if not self.db_path.exists(): + messagebox.showwarning( + "Сохранить хэш", f"Файл БД не найден:\n{self.db_path}") + return + suggested = self.db_path.with_suffix(self.db_path.suffix + ".hash") + path = fd.asksaveasfilename( + title="Сохранить контрольную сумму БД", + defaultextension=".hash", + filetypes=[("Hash file", "*.hash"), ("All files", "*.*")], + initialdir=str(suggested.parent), + initialfile=suggested.name, + ) + if not path: + return + try: + self.integrity_checker.save_hash(str(self.db_path), str(path)) + except Exception as e: + messagebox.showerror("Сохранить хэш", f"Ошибка сохранения:\n{e}") + return + self.audit_logger.log( + f"Сохранена контрольная сумма БД → {Path(path).name}") + messagebox.showinfo("Сохранить хэш", f"Хэш сохранён в {path}") + + def verify_db_hash(self): + if not self.db_path: + messagebox.showwarning( + "Проверка целостности", "База данных не выбрана.") + return + if not self.db_path.exists(): + messagebox.showwarning( + "Проверка целостности", f"Файл БД не найден:\n{self.db_path}") + return + suggested = self.db_path.with_suffix(self.db_path.suffix + ".hash") + path = fd.askopenfilename( + title="Выбрать файл контрольной суммы БД", + filetypes=[("Hash file", "*.hash"), ("All files", "*.*")], + initialdir=str(suggested.parent), + initialfile=suggested.name, + ) + if not path: + return + ok = self.integrity_checker.verify_hash(str(self.db_path), str(path)) + self.audit_logger.log("Проверка целостности БД: " + + ("OK" if ok else "НЕСОВПАДЕНИЕ")) + if ok: + messagebox.showinfo("Проверка целостности", "БД в целостности.") + else: + messagebox.showerror("Проверка целостности", + "БД была изменена извне.") diff --git a/lab5-account-manager-security/gui/main_window.py b/lab5-account-manager-security/gui/main_window.py new file mode 100644 index 0000000..aa3851d --- /dev/null +++ b/lab5-account-manager-security/gui/main_window.py @@ -0,0 +1,135 @@ +from __future__ import annotations + +import tkinter as tk +from tkinter import messagebox, simpledialog, filedialog as fd +from pathlib import Path + +from .user_list_view import UserListView +from .controls_panel import ControlsPanel +from .integrity_tools import IntegrityTools +from .crypto_tools import CryptoTools + + +class MainWindow: + """ + Главное окно менеджера учётных записей. + """ + + def __init__(self, account_manager, password_hasher, audit_logger, crypto_manager, integrity_checker): + self.account_manager = account_manager + self.password_hasher = password_hasher + self.audit_logger = audit_logger + + self.integrity_tools = IntegrityTools( + integrity_checker, audit_logger, account_manager.db_file) + self.crypto_tools = CryptoTools(crypto_manager, audit_logger) + + self.root = tk.Tk() + self.root.title("Менеджер учётных записей") + + self._build_menu() + + self.users_view = UserListView(self.root) + self.users_view.frame.pack() + + self.controls = ControlsPanel( + self.root, + on_add=self.add_user, + on_update=self.update_user, + on_delete=self.delete_user + ) + self.controls.frame.pack(pady=5) + + self.refresh_users() + + def _build_menu(self): + menubar = tk.Menu(self.root) + + file_menu = tk.Menu(menubar, tearoff=0) + file_menu.add_command( + label="Открыть базу данных...", command=self.open_db) + file_menu.add_command(label="Закрыть базу данных", + command=self.close_db) + menubar.add_cascade(label="Файл", menu=file_menu) + + tools = tk.Menu(menubar, tearoff=0) + tools.add_command(label="Сохранить хэш БД", + command=self.integrity_tools.save_db_hash) + tools.add_command(label="Проверить целостность БД", + command=self.integrity_tools.verify_db_hash) + tools.add_separator() + tools.add_command(label="Зашифровать файл...", + command=self.crypto_tools.encrypt_file) + tools.add_command(label="Расшифровать файл...", + command=self.crypto_tools.decrypt_file) + + menubar.add_cascade(label="Инструменты", menu=tools) + self.root.config(menu=menubar) + + # --- File ops --- + + def open_db(self): + path = fd.askopenfilename( + title="Открыть базу данных", + filetypes=[("JSON", "*.json"), ("DB/TXT", "*.db *.txt"), + ("Все файлы", "*.*")], + initialdir="data" + ) + if not path: + return + self.account_manager.set_db_file(path) + self.integrity_tools.set_db_path(path) + self.audit_logger.log(f"Открыта база данных: {Path(path).name}") + self.refresh_users() + + # --- Account ops --- + def refresh_users(self): + self.users_view.set_items(self.account_manager.list_users()) + + def add_user(self): + username = simpledialog.askstring( + "Добавить пользователя", "Введите имя пользователя:") + if not username: + return + password = simpledialog.askstring( + "Пароль", "Введите пароль:", show="*") + if not password: + return + salt = self.password_hasher.generate_salt() + password_hash = self.password_hasher.hash_password(password, salt) + self.account_manager.add_user(username, password_hash, salt) + self.audit_logger.log(f"Добавлен пользователь: {username}") + self.refresh_users() + + def update_user(self): + username = self.users_view.get_selected() + if not username: + messagebox.showwarning("Изменить", "Выберите пользователя") + return + password = simpledialog.askstring( + "Новый пароль", f"Введите новый пароль для {username}:", show="*") + if not password: + return + salt = self.password_hasher.generate_salt() + password_hash = self.password_hasher.hash_password(password, salt) + if self.account_manager.update_user(username, password_hash, salt): + self.audit_logger.log(f"Обновлён пароль пользователя: {username}") + self.refresh_users() + + def delete_user(self): + username = self.users_view.get_selected() + if not username: + messagebox.showwarning("Удалить", "Выберите пользователя") + return + if self.account_manager.delete_user(username): + self.audit_logger.log(f"Удалён пользователь: {username}") + self.refresh_users() + + def run(self): + self.root.mainloop() + + def close_db(self): + self.account_manager.set_db_file(None) + self.integrity_tools.set_db_path(None) + self.audit_logger.log("Закрыта база данных") + self.users_view.set_items([]) diff --git a/lab5-account-manager-security/gui/user_list_view.py b/lab5-account-manager-security/gui/user_list_view.py new file mode 100644 index 0000000..3f4a940 --- /dev/null +++ b/lab5-account-manager-security/gui/user_list_view.py @@ -0,0 +1,21 @@ +import tkinter as tk + + +class UserListView: + """ + Виджет списка пользователей. + """ + + def __init__(self, master): + self.frame = tk.Frame(master) + self._listbox = tk.Listbox(self.frame, width=40) + self._listbox.pack(padx=10, pady=10) + + def set_items(self, items: list[str]) -> None: + self._listbox.delete(0, tk.END) + for it in items: + self._listbox.insert(tk.END, it) + + def get_selected(self) -> str | None: + sel = self._listbox.curselection() + return self._listbox.get(sel[0]) if sel else None diff --git a/lab5-account-manager-security/install.sh b/lab5-account-manager-security/install.sh new file mode 100755 index 0000000..7c93ffe --- /dev/null +++ b/lab5-account-manager-security/install.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# Создание виртуального окружения в .venv (если ещё нет) +if [ ! -d ".venv" ]; then + python3 -m venv .venv +fi + +# Активация окружения +. .venv/bin/activate + +# Обновление pip и установка зависимостей +pip install --upgrade pip +pip install -r requirements.txt + +echo "Виртуальное окружение создано и зависимости установлены." +echo "Активируйте его командой: . .venv/bin/activate" + diff --git a/lab5-account-manager-security/lab5-manager.spec b/lab5-account-manager-security/lab5-manager.spec new file mode 100644 index 0000000..1fc8159 --- /dev/null +++ b/lab5-account-manager-security/lab5-manager.spec @@ -0,0 +1,38 @@ +# -*- mode: python ; coding: utf-8 -*- + + +a = Analysis( + ['app.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + noarchive=False, + optimize=0, +) +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name='lab5-manager', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=False, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) diff --git a/lab5-account-manager-security/requirements.txt b/lab5-account-manager-security/requirements.txt new file mode 100644 index 0000000..ef74151 --- /dev/null +++ b/lab5-account-manager-security/requirements.txt @@ -0,0 +1,2 @@ +cryptography>=42.0.0 +pytest>=7.0 diff --git a/lab5-account-manager-security/run.sh b/lab5-account-manager-security/run.sh new file mode 100755 index 0000000..69e794c --- /dev/null +++ b/lab5-account-manager-security/run.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +# Проверка наличия окружения +if [ ! -d ".venv" ]; then + echo "Виртуальное окружение не найдено. Сначала выполните ./install.sh" + exit 1 +fi + +# Активация окружения +. .venv/bin/activate + +# Запуск приложения +python app.py + diff --git a/lab5-account-manager-security/test.sh b/lab5-account-manager-security/test.sh new file mode 100755 index 0000000..a549d07 --- /dev/null +++ b/lab5-account-manager-security/test.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +# Проверка наличия окружения +if [ ! -d ".venv" ]; then + echo "Виртуальное окружение не найдено. Сначала выполните ./install.sh" + exit 1 +fi + +# Активация окружения +. .venv/bin/activate + +# Запуск тестов +pytest -v tests + diff --git a/lab5-account-manager-security/tests/conftest.py b/lab5-account-manager-security/tests/conftest.py new file mode 100644 index 0000000..2603c50 --- /dev/null +++ b/lab5-account-manager-security/tests/conftest.py @@ -0,0 +1,5 @@ +import sys +import os + +sys.path.insert(0, os.path.abspath( + os.path.join(os.path.dirname(__file__), ".."))) diff --git a/lab5-account-manager-security/tests/test_account_manager.py b/lab5-account-manager-security/tests/test_account_manager.py new file mode 100644 index 0000000..d0daf54 --- /dev/null +++ b/lab5-account-manager-security/tests/test_account_manager.py @@ -0,0 +1,23 @@ +from core.account_manager import AccountManager + + +def test_crud_operations(tmp_path): + db_file = tmp_path / "accounts.json" + manager = AccountManager(db_file) + + # Добавление + manager.add_user("alice", "hash1", "salt1") + assert "alice" in manager.list_users() + + # Чтение + user = manager.get_user("alice") + assert user["hash"] == "hash1" + + # Обновление + assert manager.update_user("alice", "hash2", "salt2") + user = manager.get_user("alice") + assert user["hash"] == "hash2" + + # Удаление + assert manager.delete_user("alice") + assert "alice" not in manager.list_users() diff --git a/lab5-account-manager-security/tests/test_audit_logger.py b/lab5-account-manager-security/tests/test_audit_logger.py new file mode 100644 index 0000000..c3a06ca --- /dev/null +++ b/lab5-account-manager-security/tests/test_audit_logger.py @@ -0,0 +1,12 @@ +from core.audit_logger import AuditLogger + + +def test_log_event(tmp_path): + log_file = tmp_path / "audit.log" + logger = AuditLogger(log_file) + + logger.log("Test event") + content = log_file.read_text(encoding="utf-8") + + assert "Test event" in content + assert "[" in content # должно быть время diff --git a/lab5-account-manager-security/tests/test_crypto_manager.py b/lab5-account-manager-security/tests/test_crypto_manager.py new file mode 100644 index 0000000..8a33a4e --- /dev/null +++ b/lab5-account-manager-security/tests/test_crypto_manager.py @@ -0,0 +1,17 @@ +from core.crypto_manager import CryptoManager + + +def test_encrypt_decrypt_file(tmp_path): + file = tmp_path / "plain.txt" + file.write_text("super secret", encoding="utf-8") + + enc_file = tmp_path / "plain.enc" + dec_file = tmp_path / "plain.dec" + + crypto = CryptoManager() + key = crypto.generate_key() + + crypto.encrypt_file(file, key, enc_file) + crypto.decrypt_file(enc_file, key, dec_file) + + assert dec_file.read_text(encoding="utf-8") == "super secret" diff --git a/lab5-account-manager-security/tests/test_integrity_checker.py b/lab5-account-manager-security/tests/test_integrity_checker.py new file mode 100644 index 0000000..46b6399 --- /dev/null +++ b/lab5-account-manager-security/tests/test_integrity_checker.py @@ -0,0 +1,17 @@ +from pathlib import Path +from core.integrity_checker import IntegrityChecker + + +def test_calculate_and_verify_hash(tmp_path: Path): + file = tmp_path / "data.txt" + file.write_text("hello", encoding="utf-8") + + hash_file = tmp_path / "data.hash" + checker = IntegrityChecker() + + checker.save_hash(file, hash_file) + assert checker.verify_hash(file, hash_file) + + # Нарушим целостность + file.write_text("changed", encoding="utf-8") + assert not checker.verify_hash(file, hash_file) diff --git a/lab5-account-manager-security/tests/test_password_hasher.py b/lab5-account-manager-security/tests/test_password_hasher.py new file mode 100644 index 0000000..eff7134 --- /dev/null +++ b/lab5-account-manager-security/tests/test_password_hasher.py @@ -0,0 +1,12 @@ +import pytest +from core.password_hasher import PasswordHasher + + +def test_hash_and_verify(): + hasher = PasswordHasher() + salt = hasher.generate_salt() + pwd = "secret123" + hashed = hasher.hash_password(pwd, salt) + + assert hasher.verify_password(pwd, salt, hashed) + assert not hasher.verify_password("wrong", salt, hashed) diff --git a/lab6-steganography/app.py b/lab6-steganography/app.py new file mode 100644 index 0000000..68a0076 --- /dev/null +++ b/lab6-steganography/app.py @@ -0,0 +1,82 @@ + +import json +import sys + +from cli.parse_args import parse_args + + +def _normalize_channel(ch: str) -> str: + """Y/Cb/Cr в канонический вид.""" + m = {"y": "Y", "cb": "Cb", "cr": "Cr"} + s = (ch or "").strip().lower() + return m.get(s, ch) + + +def _print_result(result): + if result is None: + return + if isinstance(result, (dict, list)): + print(json.dumps(result, ensure_ascii=False, indent=2)) + else: + print(result) + + +def main() -> int: + args = parse_args() + try: + if args.cmd == "embed": + from modes.embed_mode import EmbedMode + runner = EmbedMode() + result = runner.run( + input_path=args.input, + label_path=args.label, + output_path=args.output, + channel=_normalize_channel(args.channel), + seq0=args.seq0, + ) + + elif args.cmd == "extract": + from modes.extract_mode import ExtractMode + runner = ExtractMode() + result = runner.run( + input_path=args.input, + output_path=args.output, + channel=_normalize_channel(args.channel), + seq0=args.seq0 + ) + + elif args.cmd == "analyze": + from modes.analyze_quality import AnalyzeQuality + runner = AnalyzeQuality() + result = runner.run( + original_path=args.original, + stego_path=args.stego, + space=args.space, + metrics=args.metrics, + ) + + elif args.cmd == "generate": + from modes.generate_mode import GenerateMode + runner = GenerateMode() + # Ветка generate имеет вложенные подкоманды: args.gen in {"gradient","chess"} + result = runner.run( + kind=args.gen, + size=args.size, + channels=args.channels, + output_path=args.output, + tile=getattr(args, "tile", None), + ) + + else: + raise RuntimeError(f"Неизвестная команда: {args.cmd}") + + _print_result(result) + return 0 + + except Exception as exc: + print(f"Ошибка: {exc}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/lab6-steganography/cli/__init__.py b/lab6-steganography/cli/__init__.py new file mode 100644 index 0000000..9f946d6 --- /dev/null +++ b/lab6-steganography/cli/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["parse_args"] + +from .parse_args import parse_args diff --git a/lab6-steganography/cli/parse_args.py b/lab6-steganography/cli/parse_args.py new file mode 100644 index 0000000..bf705cd --- /dev/null +++ b/lab6-steganography/cli/parse_args.py @@ -0,0 +1,147 @@ + +from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter + + +def parse_args(argv=None): + ap = ArgumentParser( + prog="app.py", + description="CLI для лабораторной №6: Стеганография в изображениях", + formatter_class=ArgumentDefaultsHelpFormatter, + ) + sub = ap.add_subparsers(dest="cmd", required=True) + + # -------- Parent parsers -------- + parent_channel_seq = ArgumentParser(add_help=False) + parent_channel_seq.add_argument( + "-c", "--channel", + choices=["Y", "Cb", "Cr", "y", "cb", "cr"], + default="Cb", + help="Канал для встраивания/извлечения: Y, Cb или Cr", + ) + parent_channel_seq.add_argument( + "--seq0", + type=str, + default="01010101", + help="8-битная последовательность для бита 0 (seq1 считается инверсией seq0)", + ) + + parent_gen_common = ArgumentParser(add_help=False) + parent_gen_common.add_argument( + "--size", + type=int, + default=512, + help="Размер стороны квадратного изображения", + ) + parent_gen_common.add_argument( + "--channels", + type=int, + choices=[1, 3], + default=3, + help="Количество каналов: 1 (grayscale) или 3 (RGB)", + ) + parent_gen_common.add_argument( + "-o", "--output", + required=True, + help="Куда сохранить изображение", + ) + + # ---------------- EMBED ---------------- + sp_embed = sub.add_parser( + "embed", + parents=[parent_channel_seq], + help="Встраивание метки в изображение-контейнер", + formatter_class=ArgumentDefaultsHelpFormatter, + ) + sp_embed.add_argument( + "-i", "--input", + required=True, + help="Путь к исходному изображению-контейнеру (512x512, RGB)", + ) + sp_embed.add_argument( + "-l", "--label", + required=True, + help="Путь к бинарной метке (64x64)", + ) + sp_embed.add_argument( + "-o", "--output", + required=True, + help="Куда сохранить стего-изображение", + ) + + # ---------------- EXTRACT ---------------- + sp_extract = sub.add_parser( + "extract", + parents=[parent_channel_seq], + help="Извлечение метки из стего-изображения", + formatter_class=ArgumentDefaultsHelpFormatter, + ) + sp_extract.add_argument( + "-i", "--input", + required=True, + help="Путь к стего-изображению", + ) + sp_extract.add_argument( + "-o", "--output", + required=True, + help="Куда сохранить восстановленную бинарную метку (64x64)", + ) + + # ---------------- ANALYZE ---------------- + sp_analyze = sub.add_parser( + "analyze", + help="Сравнение изображений и метрик качества", + formatter_class=ArgumentDefaultsHelpFormatter, + ) + sp_analyze.add_argument( + "-a", "--original", + required=True, + help="Путь к исходному изображению-контейнеру", + ) + sp_analyze.add_argument( + "-b", "--stego", + required=True, + help="Путь к стего-изображению", + ) + sp_analyze.add_argument( + "--space", + choices=["rgb", "ycbcr"], + default="ycbcr", + help="Цветовое пространство для метрик", + ) + sp_analyze.add_argument( + "--metrics", + nargs="+", + choices=["psnr"], + default=["psnr"], + help="Набор метрик", + ) + + # ---------------- GENERATE ---------------- + sp_gen = sub.add_parser( + "generate", + help="Генерация изображений", + formatter_class=ArgumentDefaultsHelpFormatter, + ) + gen_sub = sp_gen.add_subparsers(dest="gen", required=True) + + gen_sub.add_parser( + "gradient", + parents=[parent_gen_common], + help="Сгенерировать градиент", + formatter_class=ArgumentDefaultsHelpFormatter, + ) + + sp_chess = gen_sub.add_parser( + "chess", + parents=[parent_gen_common], + help="Сгенерировать шахматную доску", + formatter_class=ArgumentDefaultsHelpFormatter, + ) + sp_chess.add_argument( + "--tile", + type=int, + default=32, + help="Размер квадрата (должен делить --size)", + ) + + return ap.parse_args(argv) diff --git a/lab6-steganography/data/gradient512_1.png b/lab6-steganography/data/gradient512_1.png new file mode 100644 index 0000000000000000000000000000000000000000..9e95b9cd7909d80e63275fea424fead3e2614341 GIT binary patch literal 2868 zcmeH}{Zms{8pqG&;*BL-14SV(RnnykwYm`6@HQ5?xX6oAi0pQ4XGDUa38=hSC8_dq z2_R4qf+CGBIH77qYu!+#3kn*_YVrL7x+^LgEINoqB7#DA+vofpyFcX2XU_SY^L(E( z=gy>55fec>h#e3@bW~(m971-0c4$6~sLQ3y6CsDGsIbt#YHNqXLMAFW#(HsV<$=IM#Q$9C~{2odac+P{6N5=zDX;hx!PF3w#f;=!?y)psIK>w z6U`Zd0dsoC0c&yu-6+0yQc82xZGgeOGl2VN1U+bRkX1%=dJn*vz%jszq!1%iE@;G$2MT=-f?GJ!WE!lvFUleobpeSQLtuQzP z?h@?)tnuY_q0dD-ooGe%IzT^B7U2HO;x4pEq!rQ%eHGxia5rE@Bd;6X6=q9mMR^xs zlQ0+Xn^(o%=%69vLt0TH0^DWT0k}7a*MmMc?3B@p!Y={+3|WA>uZw%oB7-)NR{>NaxwaNkvMrYZ6KViWn{Sq>(R$am5=yrD zE?{g8peecUx*A2eUM#0%$xi`8Y5+}1!~7H!;Ce|<$&$taeQE$rn`YLgATN8L<3zcl zwVJYqj>d`2)XlOKSr;{+=%Fr~j zbKa*V+hOgUleE+=$vgAhA^ zjeHyEOKlL)=sFCA6y<4H4?m0bqwBHWbqb&U9D?V6BTofA$_5dQp4+ir?Tz&{2e5uT z0_)x1;nSZ(^!#gbxM(J2C;)W-r#MXQ5Y}T}Vf{oF*8hUD(+xQLf`vFce+XyiZ3dky zJO%pTsxHva)o%garoh?vHQ?+q3vu>kLpZzJQwYPAr(!+45$i|)hV^wgJAD#ouULq) zuN}hKy*6XL`Xj8bslxj4aIDAS?E6mQ?6(%;>|3XC49OHI@?YCvvCkJSpV`xjr`=z` zw7msKw=ahYr~Gs{rICfY$M0F~S#V0qyTVX!LHy(Kzzm-NUG$VB@!}4!9bh0Cs_u*I4 z+bJ73-<71m#3l0 zoc_`#+IY$5)5ddz<4b<*>1}8{zJDHH!sM>kwx6fC$BQ?%B#T za&Uy_ZonNC2yQ^FJ|)iuY6aYDZ-rfSmh4BUMXfO4TJ15OP-~;^sC}i+6@@9c{eGt4&tGMG;;ie1+zyy>hla*z$pgn91Qan^{W# znDEYMBgQl=e?uB7SYe)b#-F|K?!BXt7?{nd+DaSW7ME>EMPy!c=Rrzwp#yo#*@ug% zjEltBOBvfkD=iDizy~NbUHGr7lzvZ#^p+p{NJ3?vA{<*2om66G*pUqCLOWE#&Q}z- zqJvowz~+DAIG`pQauQ`c3GX%=uHXaU~uBQ7sO_>i)Z5r;!cIEYB4R<6qaVEp*D}`fh1BG z_)FMIKlZ-B^L0HjkSjYhOmS1~$^H_vS>Sp0E=mpf!VDiNX)cqG;a}h@X literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/gradient512_3.png b/lab6-steganography/data/gradient512_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d77adffff80ca1b0e96b4c3848553c9633e67050 GIT binary patch literal 4377 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 N_IPg2&dHWl{{wwOv%mlV literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/gradient64_1.png b/lab6-steganography/data/gradient64_1.png new file mode 100644 index 0000000000000000000000000000000000000000..42017123b41f745f5efc37ec01e77be4c6fef7e7 GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7E@t*47)NX4ADXEpg46a-it*Ztow z*&VS_qHjr*e`;3d&8n)MS1rDt|7`PrU;lKQ^Pl(ss#z#M{eR`W=RZp=8SjfLT<^DB Q^ao_1r>mdKI;Vst0Q!$BApigX literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/like64_1ch.png b/lab6-steganography/data/like64_1ch.png new file mode 100644 index 0000000000000000000000000000000000000000..712195b1e6c1faa1a587db429a6a724ad953a40b GIT binary patch literal 444 zcmV;t0Ymdq0PN21eeHTLJqCMlt^zCxA+8s@ ze`EzWj<25H4fJ3QfUpqR`U)Sjw+wA-0jj2+@8@Ho0-%&mA7mPS@2R!fN8OC({n`Mb z<)BB((q2-EoF|@5_Ln71HTfzB@JF>htf`3|`#!mI;bv|}4)75fJw-+W&hb_mz~HLS zE+rv(l9xMNQxkzB;fO#ofc6f506=d!sX0B+Tzx*YB{rMjg>)=LBz mT*igjtn0o7umBd|uK=IB^MNKWOX__90000#>^v literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/schess512_3.3.png b/lab6-steganography/data/schess512_3.3.png new file mode 100644 index 0000000000000000000000000000000000000000..96fdf760e5ef658498f9b16788a0b87451932156 GIT binary patch literal 1880 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(1_pL{PZ!6KiaBquIx;c{FdT4j zndBb7^~i@Cu}y!?&fjHjnD^D1p~0SqLE#hw!=h1YGzdmh!DvPpEel4A!;w)V$T8Kk VhK4FhqyuYA22WQ%mvv4FO#nesu*3iW literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/schess512_3.4.png b/lab6-steganography/data/schess512_3.4.png new file mode 100644 index 0000000000000000000000000000000000000000..939cecd211cead7d213bf753add96fd596ff435f GIT binary patch literal 1881 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(1_pKoPZ!6KiaBquDl#%CFdQ&Y z5O+M`SntSlWIIdw{O9i&9nSxfWjG+u#vqW&zz{e}jRwJJDj3ZOqh-NpaX2z+1b*ET WRyGa42w;uLz~JfX=d#Wzp$P!972_@d literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/schess512_3.5.png b/lab6-steganography/data/schess512_3.5.png new file mode 100644 index 0000000000000000000000000000000000000000..ec100004ede82152f2fc5979cd2d93c8403d8d5e GIT binary patch literal 1880 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(1_pL{PZ!6KiaBquIx;c{FdT4j zx#rB_d-TJN*rvZ`-))&2=6$thXt3vDP&mcFuxOMT4T8~BFq#oY%YxD3aAed7a%U1) W7i`+3EDWqM89ZJ6T-G@yGywpL0kLQR literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/schess512_3.png b/lab6-steganography/data/schess512_3.png new file mode 100644 index 0000000000000000000000000000000000000000..59acd0e17f50e8a85065c08d7da6e5599fa151e8 GIT binary patch literal 3402 zcmc&%ZB!K386LEjCYElkQ4(<3R;x5k4#XJQ@ZnC4`%yIqq9!pMg7^_#MG27%SqKZ0 zq#8aJnGzL@3Y+Yj5>m}3VnK$F3FQz(L^2_|5O;Q!RCWR~OA71-#<|m*bMiw^`cvfB z+;i`r_j%vvd7ozrpNlsHJs9#JhG9W#|Ek@HVYAS27WS(jKRF?5&Y=5wYqhJN&pJ8m zv;b9xvVA|^yhxY%vi|F`Z+BHMEA9C9lj@)a`P-F6hcnLf=r^V6B6N?pU3ehr>T>R- zJxLp%c_qBAYv=N`51;HZ_s=HprTjO z%#{lY9cYgaeS~9DsgGF6nP=Wk$U~2%7YLNO?J6s&e!WG>G3HCU$yBMl>223zZG3=vXU>_X8up__2-r6_|du|R9$V zf^2<3tp}=RUll8LMz|N#^5Hp~Y-0DSf29%fp*Qp2L%9%&b?)1?2PuRu^ebslwpGRagZbSpIxwEU?hSPQHT12hjim|P9b4CJi0i4^n59$QL0U6)^8`)u zH&J!zZol#U1_Y;yS;#Tc(LRqVczPD@ z-K4r>$)|pn;jOSM7R8-In&!K@4M0J*HS*At@N@*tv~5i!NZ-NDdXVr)^a`5cJ*ehj z7x_FP*H&4Jg%olykCoJU8Gwf{)ZkUWq~0d-uye>hiiGmw^qR=sn7-NC(3G!JO*jK0 z^#C;8{2ME=j{4;^E-h)$0wX6K<>8qge}O;_TtFHjnc=s1NYy4k#HB>}j_^?Q<1sY( z2UyLsF`Gy%#N=a1-r5U+4?4X2h*cHV}9Uj+XG+BpYAj$q?Jp4m=axiDb_aHtw z$dOhadKKn$LVkb8fDUw@G#d%huOv$ZAH48;+BfUo2a~%wb%#!V3`0R(iPG+|w;A)T z0Up+N)}i&p7;_2oQgOablzVsYM2mI4qfl@h&)!3jgL6EEf=6TCK#=`|H(05)(z61E zme`0wK@~TCj)zxMCe{=3q4ux^GhmP~r)NGJ7YzGenXH?D(M*m3IT3x*M(`UB6^FMM!|F-}D literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/schess64_1.tile32.png b/lab6-steganography/data/schess64_1.tile32.png new file mode 100644 index 0000000000000000000000000000000000000000..84e2b8d595edf1e9e711dde69a5e1aeedb02fdaa GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7E@rKgKyNX4ADS2uDp7zi*OnDMv# zUr&PQk4HJJhtJKKr1>}3fg7Zpp&{4d*8k_mMkT%8K;xg3R}H^>bP0l+XkK*3l}I literal 0 HcmV?d00001 diff --git a/lab6-steganography/data/smile64_1.png b/lab6-steganography/data/smile64_1.png new file mode 100644 index 0000000000000000000000000000000000000000..84cf7c3d7a47bcfcd6c37d7be99ba1e9fd11fd09 GIT binary patch literal 959 zcmV;w13>(VP)6vuz>^+OX%btoW1tRHF3d|CP&sJfn-%5X4(d9z3~rb)XJ2xReXQ zrD}?MbnogeA`s0^@Q0hg1^szV*5IAUMsUeP!-Ca`|FxgHX6y;#)ihldOS}3cfhAjl z76OZ6V~Y}i0nVH|aiO-a_QejaG2k2C~vXlH{Yx6(a zOtVswgR4|6o!~q^)fPhvJw;@{URcd@?M9@rl*e2CTrn~y(Syq zxTa7a_gX5_acUDHLwMqY#*F|w>KhyCwgc=-y){w832RZUq)Vio4-E>ZO~#Gv6HTJlr!dm)`jb%`0+)U}_aOSsM zxQ{m5&a@PuasE!4zwRlcUDMj0V2^!kleu#CoxL64xy&B9*hE=0TYI1IQXM|>O8a2u z`+vWmvdQcNMkGLCS0Xb#adaDdV!4bsOF@&`{6rx+ zU;<2l30Nrr>-@)_C2stX3K(0af(*G#fFl(EOwVMekpte=_Ts3hUe$U>bF?Voa-iJ- zZS_Fr)-yY}{#=W`N(Fo_kHJ{ouPZ;)c|inJAn1dr3J~ac=!vL*Q_vK{zq4iR?)lAS z^bfM%K@K4_0N^d`4aXX9d!~3l%F)#e1gY5(v29v53DGU3ye7muDW$wDb_-D>rEC`B zv5dGyv6NC)3K5YBOBB)sIW{)f?GrkAAr9K+WB@n{h#FL40iyv*dwPm>!62?p1a-%? z7y$fmHI^J3`H9QL(By(hrvc!!o$d?Cgb)aU9MG1XVLO*K*yy;Iq`*Z&f!Ci;>wV*SP*Mx^GYjhh z1WvoA;8b%vJTmBo2DX$OZ|nN@$vf|f4)gjXGklqy`>Dto88QIeh#xCqUl*hLOHfrH zHt3#n np.ndarray: + """Разбить 2D-компоненту на блоки (N,8,8).""" + if component.ndim != 2: + raise ValueError("Ожидается 2D-массив компоненты.") + h, w = component.shape + if h % 8 != 0 or w % 8 != 0: + raise ValueError("Размеры должны быть кратны 8.") + # Перестановка осей даёт (nH, nW, 8, 8) -> (N, 8, 8) + arr = np.asarray(component) + nH, nW = h // 8, w // 8 + blocks = arr.reshape(nH, 8, nW, 8).transpose( + 0, 2, 1, 3).reshape(nH * nW, 8, 8) + return blocks + + @staticmethod + def merge(blocks: np.ndarray, height: int, width: int) -> np.ndarray: + """Собрать 2D-компоненту из блоков (N,8,8).""" + if blocks.ndim != 3 or blocks.shape[1:] != (8, 8): + raise ValueError("Ожидается массив блоков формы (N,8,8).") + if height % 8 != 0 or width % 8 != 0: + raise ValueError("Размеры должны быть кратны 8.") + nH, nW = height // 8, width // 8 + if blocks.shape[0] != nH * nW: + raise ValueError( + "Количество блоков не соответствует размеру выходной матрицы.") + # Обратная перестановка из (N,8,8) -> (nH, nW, 8, 8) -> (H, W) + arr = np.asarray(blocks) + comp = arr.reshape(nH, nW, 8, 8).transpose( + 0, 2, 1, 3).reshape(height, width) + return comp diff --git a/lab6-steganography/entities/channel_view.py b/lab6-steganography/entities/channel_view.py new file mode 100644 index 0000000..d5ad575 --- /dev/null +++ b/lab6-steganography/entities/channel_view.py @@ -0,0 +1,39 @@ +from __future__ import annotations +from dataclasses import dataclass +import numpy as np + + +@dataclass(frozen=True) +class ChannelView: + """Доступ к компонентам Y, Cb, Cr в массиве YCbCr.""" + + _MAP = {"y": 0, "cb": 1, "cr": 2} + + @staticmethod + def _idx(name: str) -> int: + """Вернуть индекс канала.""" + k = name.strip().lower() + if k not in ChannelView._MAP: + raise ValueError("Канал должен быть Y, Cb или Cr.") + return ChannelView._MAP[k] + + @staticmethod + def get(ycbcr: np.ndarray, channel: str) -> np.ndarray: + """Вернуть 2D-компоненту выбранного канала.""" + if ycbcr.ndim != 3 or ycbcr.shape[-1] != 3: + raise ValueError("Ожидается массив HxWx3.") + i = ChannelView._idx(channel) + return ycbcr[..., i] + + @staticmethod + def set(ycbcr: np.ndarray, channel: str, component: np.ndarray) -> np.ndarray: + """Вернуть копию YCbCr с заменённым каналом.""" + if ycbcr.ndim != 3 or ycbcr.shape[-1] != 3: + raise ValueError("Ожидается массив HxWx3.") + if component.shape != ycbcr.shape[:2]: + raise ValueError("Размер компоненты не совпадает с HxW.") + out = ycbcr.copy() + i = ChannelView._idx(channel) + # Короткая отсечка и приведение типа + out[..., i] = np.clip(component, 0, 255).astype(np.uint8) + return out diff --git a/lab6-steganography/entities/color_space.py b/lab6-steganography/entities/color_space.py new file mode 100644 index 0000000..5cb933f --- /dev/null +++ b/lab6-steganography/entities/color_space.py @@ -0,0 +1,44 @@ +from __future__ import annotations +from dataclasses import dataclass +import numpy as np + + +@dataclass(frozen=True) +class ColorSpace: + """Конвертация RGB↔YCbCr с отсечкой диапазона.""" + + # Матрица прямого преобразования (используются коэффициенты из задания) + _M = np.array([ + [0.299, 0.587, 0.144], + [-0.168736, -0.331264, 0.5], + [0.5, -0.418688, -0.081312], + ], dtype=np.float64) + + _M_INV = np.linalg.inv(_M) + + @staticmethod + def _clip_u8(arr: np.ndarray) -> np.ndarray: + """Округлить и отсечь к uint8.""" + return np.clip(np.rint(arr), 0, 255).astype(np.uint8) + + @classmethod + def rgb_to_ycbcr(cls, rgb: np.ndarray) -> np.ndarray: + """RGB uint8 -> YCbCr uint8.""" + if rgb.ndim != 3 or rgb.shape[-1] != 3: + raise ValueError("Ожидается массив HxWx3.") + x = rgb.astype(np.float64).reshape(-1, 3) + ycbcr = x @ cls._M.T + ycbcr[:, 1:] += 128.0 # смещения Cb/Cr + ycbcr = ycbcr.reshape(rgb.shape) + return cls._clip_u8(ycbcr) + + @classmethod + def ycbcr_to_rgb(cls, ycbcr: np.ndarray) -> np.ndarray: + """YCbCr uint8 -> RGB uint8.""" + if ycbcr.ndim != 3 or ycbcr.shape[-1] != 3: + raise ValueError("Ожидается массив HxWx3.") + x = ycbcr.astype(np.float64).reshape(-1, 3) + x[:, 1:] -= 128.0 # убрать смещения Cb/Cr + rgb = x @ cls._M_INV.T + rgb = rgb.reshape(ycbcr.shape) + return cls._clip_u8(rgb) diff --git a/lab6-steganography/entities/label64.py b/lab6-steganography/entities/label64.py new file mode 100644 index 0000000..6573d2b --- /dev/null +++ b/lab6-steganography/entities/label64.py @@ -0,0 +1,46 @@ +from __future__ import annotations +from dataclasses import dataclass +from typing import Iterable +import numpy as np +from PIL import Image + + +@dataclass(frozen=True) +class Label64: + """Бинарная метка 64x64.""" + + data: np.ndarray # uint8, shape (64, 64), значения {0,1} + + def __post_init__(self): + arr = np.asarray(self.data, dtype=np.uint8) + if arr.shape != (64, 64): + raise ValueError("Метка должна быть 64x64.") + # Нормализация к {0,1} + arr = (arr > 0).astype(np.uint8) + object.__setattr__(self, "data", arr) + + @classmethod + def from_image(cls, path: str, threshold: int = 128) -> "Label64": + """Создать из изображения 64x64.""" + img = Image.open(path).convert("L") + if img.size != (64, 64): + raise ValueError("Изображение метки должно быть 64x64.") + arr = np.array(img, dtype=np.uint8) + arr = (arr >= threshold).astype(np.uint8) + return cls(arr) + + @classmethod + def from_vector(cls, vec: Iterable[int]) -> "Label64": + """Создать из вектора длиной 4096.""" + v = np.fromiter(vec, dtype=np.uint8, count=4096) + if v.size != 4096: + raise ValueError("Длина вектора должна быть 4096.") + return cls(v.reshape(64, 64)) + + def to_vector(self) -> np.ndarray: + """Вернуть вектор длиной 4096.""" + return self.data.reshape(-1).astype(np.uint8) + + def to_image(self, path: str) -> None: + """Сохранить PNG 64x64.""" + Image.fromarray(self.data * 255, mode="L").save(path) diff --git a/lab6-steganography/entities/lsb_row8.py b/lab6-steganography/entities/lsb_row8.py new file mode 100644 index 0000000..317a043 --- /dev/null +++ b/lab6-steganography/entities/lsb_row8.py @@ -0,0 +1,31 @@ +from __future__ import annotations +from dataclasses import dataclass +import numpy as np + + +@dataclass(frozen=True) +class LsbRow8: + """Встраивание/извлечение 8 бит в первый ряд блока 8×8 через LSB.""" + + @staticmethod + def embed(block: np.ndarray, bits: np.ndarray) -> np.ndarray: + """Вернуть копию блока с вшитыми 8 битами.""" + if block.shape != (8, 8): + raise ValueError("Нужен блок 8x8.") + b = np.asarray(block, dtype=np.uint8).copy() + v = np.asarray(bits, dtype=np.uint8).reshape(-1) + if v.size != 8 or not np.isin(v, [0, 1]).all(): + raise ValueError("Нужно 8 бит 0/1.") + # Меняем только младшие биты первых 8 пикселей верхней строки + row = b[0, :8] + row = (row & 0xFE) | v + b[0, :8] = row + return b + + @staticmethod + def extract(block: np.ndarray) -> np.ndarray: + """Извлечь 8 бит из LSB первого ряда блока.""" + if block.shape != (8, 8): + raise ValueError("Нужен блок 8x8.") + b = np.asarray(block, dtype=np.uint8) + return (b[0, :8] & 1).astype(np.uint8) diff --git a/lab6-steganography/entities/psnr_metric.py b/lab6-steganography/entities/psnr_metric.py new file mode 100644 index 0000000..14f066b --- /dev/null +++ b/lab6-steganography/entities/psnr_metric.py @@ -0,0 +1,22 @@ +from __future__ import annotations +from dataclasses import dataclass +import numpy as np + + +@dataclass(frozen=True) +class PsnrMetric: + """Расчёт PSNR для двух массивов одинаковой формы.""" + + max_value: float = 255.0 + + def psnr(self, a: np.ndarray, b: np.ndarray) -> float: + """Вычислить PSNR.""" + if a.shape != b.shape: + raise ValueError("Массивы должны иметь одинаковую форму.") + x = a.astype(np.float64) + y = b.astype(np.float64) + # MSE по всем элементам (каналы включены) + mse = np.mean((x - y) ** 2) + if mse == 0.0: + return float("inf") + return 20.0 * np.log10(self.max_value) - 10.0 * np.log10(mse) diff --git a/lab6-steganography/entities/rgb_image512.py b/lab6-steganography/entities/rgb_image512.py new file mode 100644 index 0000000..c3753c8 --- /dev/null +++ b/lab6-steganography/entities/rgb_image512.py @@ -0,0 +1,38 @@ +from __future__ import annotations +from dataclasses import dataclass +import numpy as np +from PIL import Image + + +@dataclass(frozen=True) +class RgbImage512: + """RGB-изображение 512x512.""" + + data: np.ndarray # uint8, shape (512, 512, 3) + + def __post_init__(self): + arr = np.asarray(self.data, dtype=np.uint8) + if arr.shape != (512, 512, 3): + raise ValueError("Изображение должно быть 512x512x3 (RGB).") + object.__setattr__(self, "data", arr) + + @classmethod + def from_file(cls, path: str) -> "RgbImage512": + """Загрузить из файла.""" + img = Image.open(path).convert("RGB") + if img.size != (512, 512): + raise ValueError("Размер изображения должен быть 512x512.") + return cls(np.array(img, dtype=np.uint8)) + + @classmethod + def from_array(cls, arr: np.ndarray) -> "RgbImage512": + """Создать из массива 512x512x3.""" + return cls(arr) + + def to_array(self) -> np.ndarray: + """Вернуть массив uint8 512x512x3.""" + return self.data + + def save(self, path: str) -> None: + """Сохранить в файл.""" + Image.fromarray(self.data, mode="RGB").save(path) diff --git a/lab6-steganography/entities/sequence8.py b/lab6-steganography/entities/sequence8.py new file mode 100644 index 0000000..0b332df --- /dev/null +++ b/lab6-steganography/entities/sequence8.py @@ -0,0 +1,55 @@ +from __future__ import annotations +from dataclasses import dataclass +from typing import Iterable +import numpy as np + + +@dataclass(frozen=True) +class Sequence8: + """Пара 8-битных последовательностей: seq0 и инверсная seq1.""" + + _seq0: np.ndarray # uint8, shape (8,) + + def __post_init__(self): + arr = np.asarray(self._seq0, dtype=np.uint8).reshape(-1) + if arr.size != 8: + raise ValueError("seq0 должна содержать 8 бит.") + if not np.isin(arr, [0, 1]).all(): + raise ValueError("seq0 может состоять только из 0 и 1.") + object.__setattr__(self, "_seq0", arr) + + @property + def seq0(self) -> np.ndarray: + """Последовательность для бита 0.""" + return self._seq0 + + @property + def seq1(self) -> np.ndarray: + """Инверсия seq0 для бита 1.""" + return 1 - self._seq0 + + def for_bit(self, bit: int) -> np.ndarray: + """Вернуть последовательность по значению бита.""" + if bit not in (0, 1): + raise ValueError("bit должен быть 0 или 1.") + return self._seq0 if bit == 0 else (1 - self._seq0) + + @classmethod + def from_string(cls, bits: str) -> "Sequence8": + """Создать из строки вида '01010101'.""" + if len(bits) != 8 or any(ch not in "01" for ch in bits): + raise ValueError("Строка должна быть из 8 символов 0/1.") + arr = np.fromiter((int(ch) for ch in bits), dtype=np.uint8, count=8) + return cls(arr) + + @classmethod + def from_iterable(cls, bits: Iterable[int]) -> "Sequence8": + """Создать из итерируемого набора из 8 бит.""" + arr = np.fromiter(bits, dtype=np.uint8, count=8) + if arr.size != 8: + raise ValueError("Нужно 8 бит.") + return cls(arr) + + def __len__(self) -> int: + """Длина последовательности.""" + return 8 diff --git a/lab6-steganography/entities/ycbcr_image512.py b/lab6-steganography/entities/ycbcr_image512.py new file mode 100644 index 0000000..2a4a039 --- /dev/null +++ b/lab6-steganography/entities/ycbcr_image512.py @@ -0,0 +1,50 @@ +from __future__ import annotations +from dataclasses import dataclass +import numpy as np + +# Локальные импорты внутри методов уменьшают риск циклов зависимостей + + +@dataclass(frozen=True) +class YcbcrImage512: + """YCbCr-изображение 512x512.""" + + data: np.ndarray # uint8, shape (512, 512, 3) + + def __post_init__(self): + arr = np.asarray(self.data, dtype=np.uint8) + if arr.shape != (512, 512, 3): + raise ValueError("Изображение должно быть 512x512x3 (YCbCr).") + object.__setattr__(self, "data", arr) + + @classmethod + def from_rgb(cls, rgb_img) -> "YcbcrImage512": + """Создать из RgbImage512.""" + from .color_space import ColorSpace + from .rgb_image512 import RgbImage512 + if not isinstance(rgb_img, RgbImage512): + raise TypeError("Ожидается RgbImage512.") + ycbcr = ColorSpace.rgb_to_ycbcr(rgb_img.to_array()) + return cls(ycbcr) + + def to_rgb(self): + """Преобразовать в RgbImage512.""" + from .color_space import ColorSpace + from .rgb_image512 import RgbImage512 + rgb = ColorSpace.ycbcr_to_rgb(self.data) + return RgbImage512.from_array(rgb) + + def get_channel(self, name: str) -> np.ndarray: + """Вернуть 2D-компоненту канала.""" + from .channel_view import ChannelView + return ChannelView.get(self.data, name) + + def with_channel(self, name: str, component: np.ndarray) -> "YcbcrImage512": + """Вернуть копию с заменённым каналом.""" + from .channel_view import ChannelView + new_ycbcr = ChannelView.set(self.data, name, component) + return YcbcrImage512(new_ycbcr) + + def to_array(self) -> np.ndarray: + """Вернуть массив uint8 512x512x3.""" + return self.data diff --git a/lab6-steganography/generators/__init__.py b/lab6-steganography/generators/__init__.py new file mode 100644 index 0000000..9e2786d --- /dev/null +++ b/lab6-steganography/generators/__init__.py @@ -0,0 +1,5 @@ + +__all__ = ["TestImageGenerator"] + +from .chessboard_generator import ChessboardGenerator +from .gradient_generator import GradientGenerator diff --git a/lab6-steganography/generators/chessboard_generator.py b/lab6-steganography/generators/chessboard_generator.py new file mode 100644 index 0000000..506fb66 --- /dev/null +++ b/lab6-steganography/generators/chessboard_generator.py @@ -0,0 +1,33 @@ + +from __future__ import annotations +import numpy as np + + +class ChessboardGenerator: + """Шахматная доска произвольного размера и каналов.""" + + @staticmethod + def make(size: int = 512, channels: int = 3, tile: int = 32) -> np.ndarray: + """Создать шахматку size×size; для RGB каждый квадрат случайного цвета.""" + if size <= 0: + raise ValueError("size должен быть > 0.") + if channels not in (1, 3): + raise ValueError("channels должен быть 1 или 3.") + if tile <= 0 or size % tile != 0: + raise ValueError("tile должен быть > 0 и делить size без остатка.") + + n = size // tile # число клеток по стороне + + if channels == 1: + base = (np.add.outer(np.arange(n), np.arange(n)) % 2).astype(np.uint8) * 255 + return np.kron(base, np.ones((tile, tile), dtype=np.uint8)) + + # RGB: случайный цвет на каждую клетку (uint8) + rng = np.random.default_rng() + colors = rng.integers(0, 256, size=(n, n, 3), dtype=np.uint8) + + # Апсемплинг каждой компоненты по плитке + r = np.kron(colors[:, :, 0], np.ones((tile, tile), dtype=np.uint8)) + g = np.kron(colors[:, :, 1], np.ones((tile, tile), dtype=np.uint8)) + b = np.kron(colors[:, :, 2], np.ones((tile, tile), dtype=np.uint8)) + return np.stack([r, g, b], axis=-1) diff --git a/lab6-steganography/generators/gradient_generator.py b/lab6-steganography/generators/gradient_generator.py new file mode 100644 index 0000000..adaa19a --- /dev/null +++ b/lab6-steganography/generators/gradient_generator.py @@ -0,0 +1,26 @@ + +from __future__ import annotations +import numpy as np + + +class GradientGenerator: + """Градиентное изображение произвольного размера и каналов.""" + + @staticmethod + def make(size: int = 512, channels: int = 3) -> np.ndarray: + """Создать квадратный градиент size×size для 1 или 3 каналов.""" + if not isinstance(size, int) or size <= 0: + raise ValueError("size должен быть положительным целым.") + if channels not in (1, 3): + raise ValueError("channels должен быть 1 или 3.") + + x = np.linspace(0.0, 255.0, num=size, dtype=np.float64) + h = np.tile(x, (size, 1)) # горизонтальный градиент + v = np.tile(x[:, None], (1, size)) # вертикальный градиент + d = (0.5 * (h + v)) # диагональный градиент + + if channels == 1: + return d.astype(np.uint8) + + rgb = np.stack([h, v, d], axis=2).astype(np.uint8) # R=горизонталь, G=вертикаль, B=диагональ + return rgb diff --git a/lab6-steganography/modes/__init__.py b/lab6-steganography/modes/__init__.py new file mode 100644 index 0000000..8bfcf26 --- /dev/null +++ b/lab6-steganography/modes/__init__.py @@ -0,0 +1,6 @@ +__all__ = ["EmbedMode", "ExtractMode", "AnalyzeQuality", "GenerateMode"] + +from .embed_mode import EmbedMode +from .extract_mode import ExtractMode +from .analyze_quality import AnalyzeQuality +from .generate_mode import GenerateMode diff --git a/lab6-steganography/modes/analyze_quality.py b/lab6-steganography/modes/analyze_quality.py new file mode 100644 index 0000000..8ad59e4 --- /dev/null +++ b/lab6-steganography/modes/analyze_quality.py @@ -0,0 +1,41 @@ +from __future__ import annotations +from dataclasses import dataclass +from typing import Dict, List +import numpy as np + +from entities.rgb_image512 import RgbImage512 +from entities.color_space import ColorSpace +from entities.psnr_metric import PsnrMetric + + +@dataclass +class AnalyzeQuality: + """CLI-режим расчёта метрик качества.""" + + def run( + self, + original_path: str, + stego_path: str, + space: str = "ycbcr", + metrics: List[str] = None, + ) -> Dict[str, float]: + """Посчитать метрики между изображениями.""" + if metrics is None: + metrics = ["psnr"] + metrics = [m.lower() for m in metrics] + if any(m != "psnr" for m in metrics): + raise ValueError("Поддерживается только метрика PSNR.") + + orig = RgbImage512.from_file(original_path).to_array() + steg = RgbImage512.from_file(stego_path).to_array() + + if space.lower() == "ycbcr": + a = ColorSpace.rgb_to_ycbcr(orig) + b = ColorSpace.rgb_to_ycbcr(steg) + elif space.lower() == "rgb": + a, b = orig, steg + else: + raise ValueError("space должен быть 'rgb' или 'ycbcr'.") + + psnr = PsnrMetric().psnr(a, b) + return {"psnr": float(psnr)} diff --git a/lab6-steganography/modes/embed_mode.py b/lab6-steganography/modes/embed_mode.py new file mode 100644 index 0000000..3e4946d --- /dev/null +++ b/lab6-steganography/modes/embed_mode.py @@ -0,0 +1,40 @@ + +from __future__ import annotations +from dataclasses import dataclass +from typing import Dict + +from entities.rgb_image512 import RgbImage512 +from entities.label64 import Label64 +from entities.sequence8 import Sequence8 +from steg.embedder import Embedder +from steg.extractor import Extractor +from steg.component_pipeline import ComponentPipeline + + +@dataclass +class EmbedMode: + """CLI-режим встраивания метки в изображение.""" + + def run( + self, + input_path: str, + label_path: str, + output_path: str, + channel: str, + seq0: str, + ) -> Dict[str, str]: + """Выполнить встраивание и сохранить результат.""" + rgb = RgbImage512.from_file(input_path) + label = Label64.from_image(label_path) + seq = Sequence8.from_string(seq0) + + pipeline = ComponentPipeline(channel=channel, embedder=Embedder(), extractor=Extractor()) + rgb_out = pipeline.embed_rgb(rgb, label, seq) + rgb_out.save(output_path) + + return { + "status": "ok", + "output": output_path, + "channel": channel, + "seq0": seq0, + } diff --git a/lab6-steganography/modes/extract_mode.py b/lab6-steganography/modes/extract_mode.py new file mode 100644 index 0000000..b091ac9 --- /dev/null +++ b/lab6-steganography/modes/extract_mode.py @@ -0,0 +1,38 @@ + +from __future__ import annotations +from dataclasses import dataclass +from typing import Dict + +from entities.rgb_image512 import RgbImage512 +from entities.label64 import Label64 +from entities.sequence8 import Sequence8 +from steg.embedder import Embedder +from steg.extractor import Extractor +from steg.component_pipeline import ComponentPipeline + + +@dataclass +class ExtractMode: + """CLI-режим извлечения метки из изображения.""" + + def run( + self, + input_path: str, + output_path: str, + channel: str, + seq0: str, + ) -> Dict[str, str]: + """Извлечь метку и сохранить 64x64 PNG.""" + rgb = RgbImage512.from_file(input_path) + seq = Sequence8.from_string(seq0) + + pipeline = ComponentPipeline(channel=channel, embedder=Embedder(), extractor=Extractor()) + label: Label64 = pipeline.extract_from_rgb(rgb, seq) + label.to_image(output_path) + + return { + "status": "ok", + "output": output_path, + "channel": channel, + "seq0": seq0, + } diff --git a/lab6-steganography/modes/generate_mode.py b/lab6-steganography/modes/generate_mode.py new file mode 100644 index 0000000..02f4663 --- /dev/null +++ b/lab6-steganography/modes/generate_mode.py @@ -0,0 +1,40 @@ + +from __future__ import annotations +from dataclasses import dataclass +from typing import Dict, Optional +import numpy as np +from PIL import Image + +from generators.gradient_generator import GradientGenerator +from generators.chessboard_generator import ChessboardGenerator + + +@dataclass +class GenerateMode: + """CLI-режим генерации изображений: gradient/chess.""" + + def run( + self, + kind: str, + size: int, + channels: int, + output_path: str, + tile: Optional[int] = None, + ) -> Dict[str, str]: + """Сгенерировать изображение и сохранить в файл.""" + if kind == "gradient": + arr = GradientGenerator.make(size=size, channels=channels) + elif kind == "chess": + t = 32 if tile is None else int(tile) + arr = ChessboardGenerator.make(size=size, channels=channels, tile=t) + else: + raise ValueError("kind должен быть 'gradient' или 'chess'.") + + mode = "L" if channels == 1 else "RGB" + if arr.ndim == 2: + img = Image.fromarray(arr, mode=mode) + else: + img = Image.fromarray(arr.astype(np.uint8), mode=mode) + img.save(output_path) + + return {"status": "ok", "kind": kind, "size": str(size), "channels": str(channels), "output": output_path} diff --git a/lab6-steganography/results/00000000/1.result.embed.y.png b/lab6-steganography/results/00000000/1.result.embed.y.png new file mode 100644 index 0000000000000000000000000000000000000000..4819ce14b92e3df31ad43e94c0e5f226199cef7e GIT binary patch literal 70349 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

    KBC4qF@$$5PZ5x|&Ee?8Hc_)o1__^2PM18p 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 literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/1.result.extract.y.01010101.png b/lab6-steganography/results/00000000/1.result.extract.y.01010101.png new file mode 100644 index 0000000000000000000000000000000000000000..a1501bb4ab3c692e9b6bed2de6226de88746157a GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7E@qo<2wNX4ADmkqfX3^-U0{{6q) zcczG^dd!5mUPqi<85i6*_hZt^@X%BCbD!*BHa$5%XkW8Uxx!Y7k6y}c6I9M_WaupB U{(4mT^lOlzp00i_>zopr06k$ z%q`R4HQ~?A3unEhj1GFprt6$*P1)p-(pXj7%HD9J_P^!*c*h4v>}O2R|LyRAB|)B} gp;qBSGMr*CdB>z!x_jo$r67AeUHx3vIVCg!0D6rttpET3 literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/2.result.embed.cb.png b/lab6-steganography/results/00000000/2.result.embed.cb.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ec3bb4fecefe529f79523181ecf163284e6312 GIT binary patch literal 68238 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 literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/2.result.extract.cb.png b/lab6-steganography/results/00000000/2.result.extract.cb.png new file mode 100644 index 0000000000000000000000000000000000000000..1b662e867a995d8a2da53e385def8892b3c0c281 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7EDyr+v}NX4ADQ>?iT81Ni@a_|4S zcN0=LO}8AK;F^E(xMM<+$eAZG$-6ri&10AtBXV-p23sx0eB}j<0{#DgKdjlu$|zgB v!L0uI!y0a;FO3aq4R!(yzZ?#9K&TVER@}bP0l+XkKtQ$6F literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/2.result.extract.cr.png b/lab6-steganography/results/00000000/2.result.extract.cr.png new file mode 100644 index 0000000000000000000000000000000000000000..c5c907a9c8d4741906d2810c4507a2b2bbcdfa02 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7FuEKe85kcv5PFM0Dd7;vxzysLj% zn5witO68i5j&$xq{{Yu>4GuL2bQ9kNt}u1oVC~PslCqP%?BG!=MfWZzhK-ybUu$r@ z;L7-xFuBEP+s4+VOp~6hS#Wvf1lzQ_t{4du3soNXJBR97zQ)@N=)GRQY=dkltNmrM zJi9B>P5T14_*QWRFilcsX1pX^GAXFQ(@Akfs_>&*O%2Nm7&?EvQn@qf{%w$JJzf1= J);T3K0RX21O*Q}k literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/2.result.extract.y.png b/lab6-steganography/results/00000000/2.result.extract.y.png new file mode 100644 index 0000000000000000000000000000000000000000..1c00bed153db66fcef7615725332615209f3067d GIT binary patch literal 353 zcmV-n0iOPeP)#I|9_r+uopxvAnvxQNy8|GIR*eE0HQvuFG1E%AydfL`dsI(B!wtIfe2N( z2>E_wLixWtX2^HR?N+o~XL4ZcgB<*+lC`U{%Yo@l`F%T)Ov+B@)``5%kVkygd0pEJ z3`fhsP{f#H7{tAYA(f02L)FeZ43T1Z9oJp)G1Fd#r)o1)$40fp8B)Z4&yYr@C5D{| zelWut=b46=<=B#9xaxeHDZ^0v<+?a~84hg?F|?+#<-CFW9}J(Svcq}R?K=!7Q+eXo z0E`FHZy6%Rur!LSR*8LD=o42febXU1BN;dz;p&hKGp_!StC zF@{Xe(!M^k%iRoTQ+b2)-b@9AT79UANeRFg@?@RQdW1l-00000NkvXXu0mjfJp7>q literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/3.result.embed.cr.png b/lab6-steganography/results/00000000/3.result.embed.cr.png new file mode 100644 index 0000000000000000000000000000000000000000..d94bc1542edd3754381a7dc6e24021a50358763a GIT binary patch literal 71685 zcmXV%dpOho|Npn9medqU7!x7Mp@=zcdZ*-26BU(Xl%z1^xY;V@6f0*rOmZfNBxmM0 zhnPbSIgUA>nd1z$`&d| zx3&t`@zuM9(OWqMeV$&xZx?+PC6}yK)kv8m29!aB3G2r+P;JBb8FWwt+=n}$~nR(qo!4@d$5jAgtxAyN{D$+`m*oLE3$Qmky*bUvZQW5 z)~@KY_?+fa|I24s- zZFZK*PzLJo0{M?y$Dk=b=VwHU`SZaDfyYWwcdn=LUsa9poMHYcYFg*~%Stx)xmk)> z+}#VOx0${yXTMjr996yVRrJQ-=SFvWM7(moOopq*(!k-)bJ5F%c&U%o4cI>Or{36+ zq~!e!A!#FW!5nfaOxWW)&7(1)z*R2}b+2*1rht@d#&@Xrb3wJ;pwLe&PX2XNhhx;B zB5i=Sd(+~lemBi)tT=I51HbFBF&ry_Ni>wA_V}Bu$L@aZ|DK5IF5YwrY+hX-<5Tq- znYL&yyj$>1=+K8$l+Gw&jpwX>PTozBVy4sRK9}0_)!q66aB;|p;vBvbg0C8A$A0uF zvtM1*=$)=gpb_Rbb_Pn~sz(>NpRhd1!_z(XeL+R95<`n^iSOFayoH=)Q$sGCo0zuF zq?$=2|BnCh$G}Kx-Yoh=ZQILr-DDNk@FgVCzEy{HKL1E(dQUu^sK{E;k53M{kSdNJ zP>Bz8QClEC7~R%+nfJ&{4FBWmL4l;uha}rk=-2$x*zPj>&eyf_zxN7l$5&{wnC!Nleh7Cf7;IWT-RRThg!MAL(2p zBj$}of^j$1x7N?u@V(3*KJ~j{d|R(`XY@C^eaPX=5e-#lsoF>V-zVS)7qYmi&Vf?X z$6%&m;nVn~pmp{)jlRVMq-YjN%8qJsY_?G8W|-80B;2{Cy_mYl7J;7>maj7RT27Wh z(!qGRIyVEf6CTIsKB8R=6KVi|bLz^wD6&(Upn^riw5k&mYru1PvO7AGKZ=7Ob56xI zyFweP_26%P3!c20-(#}~>nCAJ%e4}JyjFEeCQd>Z7-2%rl&}Qasz(i&dvIs9#DV7w zw)q^azfOYgp+b_99RpSBZJ3{~0k2^>qwBH6EmXCFym>9Sz-#RkTw&$&y{-i&pV^Nt z^aC=DPAnSV*1^z0RD{ynXn=mN-ph~L4BqH*aBc#vfX)Lev7P4H<9>RB9JxBq|DCL< zu7ih5JB45_(TQXD(7dY*1G5HjzGQzk`qo)zV!O?p%nhuT5^5EA4HSuNB)tNafDWTG zRpA{wk{+yKf*!7xPV~e*sR#2Fzwz7KuK(S>Osdlif+VkUQrpe(O&U~A7_xRW!EZo{ zyHP5)5pv(ASVy%`7_QC^XJj&V3|AvpxIbisXRjgl>s`PcTZ0aXIAPk_j?;Tm@ zV%b3y>wH_U7{7M;$Y$wWr}_meg^6D|kmbm@{n)eOTCYipzfNb_k520)f`IG}lYnaxBd=m0%@r^_xsl zYY}(GiO=Cn!bnQL*I6hofJFVqL0b-Olrl`^GYiWdBhtSlNVf|9P0VgCr$>!#n%86!%nE2awH>%<%HT^*S*M_PfS z;oIUSo_eD^WO_95cD=+F19T1TU&UGOyOg=HSiEW{6#Z`p$N~D!8S!GQkmrgX`XI%_}n5ky0^P&4z z!33YgE<0ypdYsfWZIU5e4PB}Q`(mAmPSd-8MANFv9id7rhtx|9qToO_GO4jugbFs7 zn=C|%x}J{yxPJ>+`l^Xx!H|!H)3xBGFPVBWFOtcRH>MYrU;&L%&xN5lNmM}qWOLn1 z3b9P0fVZepGq6OXLxakzaY0DSpXx?WeEmoejf0to@RMz+6@HK*__Oq&QfCXY2TMl= zX~oH9Q499iDZPdV?!CBCN~95Nva%J4ud5P-)~|cnRn;cOr=EUOJ^jAgtOl$;qAhvH zV~qIbdct$aoh1pl!h}o?orqbBNL~$;K~m-z45GVySGGD*3qNu(47g$6wmEtjDZ#j~P03 z9q?K(%?=y)4C_e5APfy`-*U~nLB<{M%+0=m8Aizv`&zh0&|Ba381&~azKL;9Q^yp) zZ0iXx@~BSTcstXk?dz+RX=%~EOKYDfnQ^sf=DzUm7o)T=@*z`dAlOFvLuF-LYkywl z=LFw(EJt6EM2Y_B^zg0bmk8TNQURNoOgrzyxdsWUbj4eK|ET`KPD#MSpdNO{teKqA z=f4$c^6`}&+;Uhkj8mQWudP%z=jFXhS#GOlbXPeCR%#%dd}HkD6q!{Ye=9`*b36@In3g!=6rg+gt0+Rc%4;Bw7q7d$Vptn-se-v)VLT4bdFh)AP^i8C?S zBU;Z8!4HKq!mcLr=QuuHfB_7PDCCyE7r@5=a$*e{yxzt>%Dwx{K6-TYS*0O`*-C-U)e1SFi zj!mrbn9{{}oXkx=sO8!L|JIZ*uQ=6up`}A^VoGOCDxXkN`AqTNm3>AB+Vc+auMOVi z;K}BI)|+JJctRc})OcbNy0Bb;>b5?s{7W|WdpE}r4(BfP;)ZrhTi#yMm21V3pN(?I z3+u33E^98nfd=j2n?a8|)yccGrb4!M{^1{O-1LWgh8A}u$GfHt2~SQ>U7Wz2bqV&p zssEY@X&U$?=$brP0dKdZnK-}n!O3rkHBUe}XeL(b2*cb^tGAq-x39xtPgu}>$3H8^ zNaEPElZL}=4eq^^mtHxm0}hSvusa3i*ismqMEPg-9n|3 zr@izpP?68h;fH+PU)p@X)DJoBvA6d|v)5#SEl*1Kdzwqbd#PT2%yLZZDtLviF-{hN z!nswhfw=ZN*~h;uQ^0-gk60j#{kl&4cKucO%5&Vf(bAKRNF&JrOvhyy2)@e+*Q!ME zGk9;4ufm<*rrSmpyIq}o26v7nZTT+>Np5-jk#yv18|;#Ob9NY^8Fk6m;Ne162>fIez`Fz~qeyDMsm-?lxe^aM0Uv(2RaQQ2Eaa*3as(>Puu^(2f)bDER} zM$W>`O3GJ9o|Z;0O)m9N$b*HU?O`vU3zpzTjU<|GqLELAHGIV{VR>2TOe1*fFR(8z zjWNs_(s#wVhTcKC25iT-#cN8jC!k5y%uBF<@vtHn62VOf=IMYN?~h96iZDeLQCW7Qlekcz_=tr^PBws5{_ZGl3oXAM)6{af%?wf;irF8lF7|!2NjeFQQG5;z zHk;Im$7IB^+`VAAHNDRhi#Xc5tGu-eYIxE zTE1G*kDIzo3YmNX0leXpD2(UQ+DD|xPFjfQ_bhWr)@DZ=XNVZlQ}S;&bhN_c=DX-IJ@*Zs&cmQ!@KLdL7N} z)9u5^ZRKuy_511fh&adL?%1R6N%p=~wZ0lwaF4GQ@gqMw)`U?Q4Z_=i7eCJR4UTUy z%T-R?Za)5is$I`kIrz|d(1CWLC2`V0N4n)zN<$&em`Dz%O73x@Oo{fRpQC6;+>=i$ z&l0-?VU*|&2$Fs#vC9ZIp3UUTVXMMc7`)fuE6|nIB?@?o8IkUG5d|oq0J-yCT-?`G z(~vF(mwd;Wi%ni?B0yJYjXTDSsMvov%d6AQm`|Z@Qtpg;@1e(ux?aTei2+E&sDHX` zd&Qs1~6aN5<@bu00f#I|wx8{?M8@Bn9l>d3es5GVoA8+L>|) zGh4M?zxo%mZmyAfxZ1~_^xDQm7-ss{SmJ~J+tonHuWs{$o_b%R8O&98EJapBA`DgP z2RTDcnD!tHv=`Ym;ky5NorId|dme?J*V(B$Ye~P36uoFSnUe~PN2|~f_Mmehqa1$~ zBmKg};^2QO%2Nu{%nMYxw2ymL5_h>85@}V_J{nlv*P_12F7flyTR-wVEFfSOv9~+1 zye*)Vjif~OR;@Z~B@}t8hd?Sc?*sc2pq<9gCGzMCVG>HctxTT#2m8pN{wJKu-lhL+ zqC((FCi>)|(`3=kv6~gUjE zJbW@;@ef7)1^1|HgVB3wmG~5bH#J35eMbAmXq?4$LPs09zYffcKIV4T>)O)+EzSqf zPuwzNC6b{#VDyyFCuy-SsEyb!1(9VesQ3*Qcy!-(*KTdFfX2Tj^-%@3m=F??b={}e z-%B;FC|k^OP3m{T7?-4S-i`2v|1N$Xsa5Z@wH_+UNL(cX@02h_0*}Mv%K@v z4}Xa5f@}7ir^^2R4KCI#{nz^kM-sbkn2GVsQSoqvfu8NMITKY9dnmP%4+u+4DE zJsQ855_pjsaCkw~NR9D}Q9^V=wLr9C1WD?m7gCh6M52S7R%blTyU+nY$ihnn_l@&X-K$b)skp;=m?;(C#B{&O z@&$InYGBcm<=t~xJl&(L-4@y%@-^26^jzv^-*;y3wZU+O$Z9{x5zA&O_&RRfE72$z z(@}w-CA2h|pD!@cgsnBz=w4O?-d*JKrsnWucq; zNUhvn0w44b#PB=HwiN}t@Ze4GSc0GSPhJF}7yU@Os#>|PE&6~1hKyoFC!tK(-$X6P zt8nk3&J;eK*;9#Kw~=%n%qxpU zUT&QDT78SXglFSnP~15LCa;%3V}KkKgCL(oJLWXT@-%}X4{+fZfX6MG*dZ;~fq&tS zK(|Zk9r)*%=in>n)DMIiyrV?OOV!5F<%V*Pka9aC*E3~bX35*TsY~|{E(AgDgv+P&lz-Fg%C?Y*+*eJw!UkzAR?*7NCx;*l^Ndgb^LGbm zdF^yin(xqTWy|gTCVbuci@mLf@K47*REy;w_epjgky2~tCZdzFJeC}Y8)oS0brTr3 zV5*mE9vPAE56Lp9;HuVgohVID3s=FY*k9#Ny1&?)R_aUIEByLEJ0-_1ErAXCfLK7Q z|EU?aF?X_GlR8V&zqR-woE`Xxu)nZi!s^rzFQ>A8`nGXv#jbp8na^`!UbDMo;|q$l zt65wOzV0Ywk$K^j1UhNG&e{T2wHJ87yQ=oZzV?;@)sEvSTzVtA5L>)@emUjBcJ_-y zdM9kO&2I1f4*zWAbW0n5CYV&|dBx~=p-sC4cT(FAg{2pfZ_@qBLiXxX?Q`yEy}B=% ztW@i_r95_kK4mfYC<-{5?Y%GSc`gzZ==GEqfTSe%`eZAF!2Sh z$q@Bw0cgb=l8(0gjD!wi@p@P+-4SkO5ooh|hE&12^UyT2JOG@}8M7>Y3) zllHR9&5cY#iJ~g*2>#68-83ao+J`GY#$TMO^};8HLd}9OF)q;w)QRm$ygQ0LVVY`p z!3(*5?9fq`PQIk6EtM@EYoZ8<1|sC7g)D=3_}&{Pf%$cOs5R>A1rDzU5S2ycUfKWNju?ftt1A$P2 zbIps?uDS%)#~T zT@Wl|{?`^A^kI)n-6{EUNTVbPyt)sb|6R++)@ zrN~yaF6u$z%Q5ljL52YmcD!{<2N5#JxY>T`&J*-?8?`%1)9seGQie?yD*M_tZk~*G zKIm^8pMsu#uH1RupF(5K8 z9X?!M-DkHzUW+c_+iROs6lCEdoXD46zInN6ir^n?IV{(r;#$j;I#2j-*I%E^=oSd6 zHG9tvTpD_Bk8KpLDUpE)yc%3N<*{ogfwo#VmMW_)+@uay7-TGHKaNI&U;D0@gCERI zLjQR1ROCt0?m6n&HYPN4J2wt1$xGE#4;VSSeJoCxEbb*xeT8;!wR84QxLg_KM$-+d zc`7GThsKDGC71UU4?g|0r6FoG#s-~1filTR%0^!@k`6pUkBMIFoqtRF(ET!Q=%>$! z5R4MOm;H@bLqhTU?4|Ykhx(VR2dU)*5Jq?DFc#@-^bu9ej4(P`I+58J+ivM9FQ zkp588U007`~5k=4lT2!W~G2yRg%8|Cwq!xn)h%L z9%KLc5)oTLf4e-G5uvYkKX3avn7HD72`CY3*Q!_Z3TcE*gf@0K>&Y{xGi4Cy1W)Sm zZHM9RGCVgggX@xWMx37#@vpQTVEC7>a&G8+5lF3=6_LDus3;5QU}-v#f~~PI*p`8p z9xxHEIv#SrI#Bu!(mo}l!B5VxM7950N^Sv=#A$~4h|0_L@r}6-Cu=y}XLTB@#d8!z z)=Fj)&O%qr+S8qhpAi#xhTcQiSGEwEh!y37Ci~@ACH0fim4JgXE(=3$>Q;`2t5k6j zd~g+1FTFG*l5UL}F?X*@?=mq0hU(I4X+nZ3#JwK;R6bOkz=5LfeN%vyxb+%|M*ra8 zLrh8EcK){q05kTx)xbN5{;C&;p_dj5mgvO%1lNnJ7b#%GgtTT0b@x1G_9!&sO$KWy z0P<&DZlH8O%9}I%L3LssSWfOTPpH(V6*gihSbPrg9;+2m2(Jg59_$oG0rq*2e$}gl zh~ZyI+LMMOZ#PSSLiZp$$L_*ca2D;FB@>+Rm7fWtd|PFAQ)fDY$3bb;d)!|iO*>OM z1@g6(X0w9XAyh0Vm$MN|DfG$lZztmAF}e(1U>LG70j|=wFf`oye0aI4-PrpBY0DNT z)?$3cecxwg^_JwH8`W{%+1qDf+hYrN^gJOyzWq1<)bDBLfyiOoIj%Cd3wCd)2^m!v zzAXRvK`k455LdpHHFhL7?|tEk`cDA?zD31R5iRPHO=LR1H0kkes?5fU3a}!$G#&DC!sPFCg&TBa_shX;^~inmzxjm6t_Cztix*rDdQrxLmJxvIRD# zKe$l>&Fk;JDqlYmTK?PuR`d6Wy8vf3H1h27`!1H9$(L~5K5?(J8%3y7Z+L&NxBOTp zK;s%K;P*18CNqAjoqM(Nflwn;8NM0ZR@iD_aKJ_n-2+CLn7+nC>R0Kc9B*Er2?%YP z9_UXei+W;iVz>XTsGcKW6{j}uc zyX&fO!=89=G^MQyUU=?MqnIv`@vOOt7%DDYTv*L6b(Ol*- zKoUq>&N#7{Jo?`qb*2lutImFJUC2?mab2E$d*|=X*SA-K2yUK7E_EJ)HNDdO9JMWE z&egZ2@Nl3T#|gDH=hY~pdV`_?qugPY6Hrm-eR41?oefnAxO`tQeos3=z0k^pdkoYd z@z3R0TV=V(W14%?eFaDuj>U@LI$$#wUkJaV8hC&G*0>sMhX06DEtqpZ^+8e8W0gb; z`9#F2N&bglT~)_4+svzl_7X&4o@b-2yreMpH`)bZD=U)~w8}82LZ%HI(7eGAUtZJ* z;BoM;Y%$#(9r1_1;G)8)>xkVrBh23CRwP~IVCE(~pLXB023)D~#tyCOy96}&3{*5* zyw3R87|3VCd3ZAq33@pgTz6O}=o{?@{A2*eRNYD0fJ7(i<0_ujoy-XxC&u2dfIwHe zQdZ9$%$$PLn}8RPRz6>GW&_<`9dlQhgs87}82O z+H931GA?}zMZFIDUCEm8lYyA?Vi%>-dK4S9Yq@(R#gzV(QOio-yX$ldkM3(PVtS)a zIf%CF*t!pUA&u>R-Oz_1m5!ZlrB+$R|;y5)8J!_$A*FD>F>3HZ}*UZJ*eE|)@hoa1jh+nQNMPp019BZ=w$L9{qUw7BvzDpv_ zbBEW_m$EY0w{p9O;CXWqclgzx4qZmq!@Y&XR|?d(aV7ltH(2UW_53C^;p6ERgHkp| z)^DupifYJ%5T`KrtLc$!;$0QRr5C&`Ht3MCQ&-GB%2~_ugC}Uabgkb4CjwoVSByOv{gme{jT##RiAVtB;D`G{V5YyADgcE7 zl>BIw^{%@wQJ(yZnLBz2Y4xe`os#|MaUw_ff+}2;*F0gO;;OupCe{M&eR4ALbywu; z$CvbjpPIP9hF%Yr#;0yNN$5v#joE^IBC?WQ0|6_3dN<3o}FU|hP2nKSTr?# z5oaQ?To^@rCH&#G<57A9VPcGUZD83S5@WoQBk>NRjWAaPaCLofiEaFWokr>dV2U!_ zi)h&P15CqCyHLo7p*yr(y6bT$$D&4~v6}VtXd|_}!l{46G`Mk0jzP>H6>b3kl)3%L zO$2Ice+0UKk)Fm9Wvdael`z(j3qP#nM6^aQWPFD=ahYI&7*+K?1Fc`gErsXKFi&Wt zUO>pV8wa7}EB+RoFslRqd~(M`ben;+GJ!Fx*GblsuKRaMkRh)H5LCPGmF9k9s7k>H z$N;n1uAMj;(mqa{x0AhrrSSdpzTVDU*GS#PYSp(3qqiQYSMx$~AJYLa$jk=90e%VH zoYirE?(|}{Y_A^Nfq&|q8u>Sss&4A^9&29&puAEJT`+Y%4=791u4z3D3cgomj3=79 zrvP)FOzJXW55*){)`CMd&+hO$2g;IxB4&kk?+L}S{==39%v$bK%a?zby=p@L7->5O zYr5Bm$fFZ)5Kj2iQNh3K{$fsRLX<-xB4~$MNBGGGiRCfr`?S`2DKq#AF(LbB@>J#j z7|Cn+O6<1wHvF@+TxT|5n$LU}>robA4R2=$wvT>*Y^TTRtWYWDG+e`XY{3O(QHzrVb%M^3ESy^G19`2HX<#BAg z9jhmoI(*e)xh@GZLYCSPKEb~R>32V4Ctf%QQWXffJ{-^}dHuXeKdJ7{giK za_%aP@~S)lK`t%k6?OiiR_^+{zY?uS`K62=pPw4OH5-Kg0cFS)E(-J#T3a^{|5}`a zYV9?!ImKG?`_Q54@@UFO_0M%m^JM&>d+vbU#JbQQ`7g+`=X!ohJKPai{J~k^6!z@V z^V7%4elo-5!cYQ(1W}v%}jPi%9 zEgbI;M_SSE40%qy*v^qyFCRPJpHFZ*1FZ;8x7`5TbWb}9%iWPZ^c?r!Bf(!xCkCV8 zA8d`j+6cOp~t*_JfYAMi_a$U8&zDZ zAVxSatCr0F?wJvpFHD)ZR%JYFvBFaAMK8CRY)2&csB!FG1niYYDwDx$QJ&1Aw>{Y` z6?)4SzKypqQ2Ej~P;F$Ym58qO^dAHy*F~w>i0WjdXucyC&zT>HU>*-T$d0t3j->=D zTA^EvgBqm(j(Pl^Wr6EX#f#~@A1PYeGQhxBYp;HQMC273{G*zL&VefHMaB0F=WGi$ zu#SSOpe#>h()PaoYM{5tyO%s>f~|%7ccDuBOY@OTBt@op4CG&p6@odlhI*uC{@@^( zSuFhIFIVcad&)|Fb$1oY7tly1?U#WLRak4hw#DT<0=bsR6LkSWLfOwvpYudswVSb+ zI;bBFllLZY^eq^6?_w!q0{OHRm8N5E6@i?vel*0LJyoMTA{FhOikZc$t7n)liPO?WwB<%{;odtPPVc6^i|auZy~Ch@8;WDWH?9B@@{Sr(+zis{7Igw_ozmV&$(!jH-Ogi;wNA_~r* zeUcS*M$tYdd*wfOZ(RUwZO_ZwhhE#|8vg7$TSu-%oM0q?2buO7%P= zo2L!)rlIRq%Dk7cOC{46+N)wFE++C)-qBjG<1h8b-Qd+tF@H-tJ*Vg~e19}xvggEN z))3D3^Tu`~lh5G5Z3nz~l`Hai^?RRK8-Q-OW_At6j7k1dZV&RQs?8nM6wrB^@$FSz z$^1>dbeh}H(_b)AXQtPTz$`*c|GM^|vfVR|n=QB@FE7>ViQ=oZ+)fAXb*Eez!A_SF zC;OOuC4I)0cszc<*8G{(zy@(ybopAe zH{P2vOCxNc4~>@ZH`QKBVG?}arBuv*Nt!3k+y@ZR7m<&UnYV;LEdf3caJ<~mk5$c& z0m$_x-3=m_*;j`oW~ODkA(Ot}b7Ps&r4#a96Y0eGI4JWp%7PD~xT0Ss|!4zs(SdK;`#+>vEFYF5EYF6#dq^d&~A#zA95 zhlvm$XOL>y@YCrk^I<>8zG-3@AItN_os(~MGWCkrA~?Vq1V9S}#DnMC4t81bjbK5t z=W(b4Tf+~MyI8Q#r;+-8yZ!`{4*0~J>Uj=Q(!6vY))Dnlps|1B)+9kt#ZIQOym_%o z{A{X=6jw7u!BQHD9Re1Pt=dn>j?C87`ZYs zFKOmt|L!$+G;X9FaO-f6qxrc*HgkV3caA;2rHW@3&*((5m@qIxN1!sjGu0hww# zjk#Kn>{4z0;rzbda&LE+sc)6-gZ@GhuMOkKdJFB4rtQZI#VMHn_1{T7*}lGaeU80* zry(SrHQZ9-;H5g8KTOvjobE>-kKRZ{FJr5>f)uZX=*Z*P99(^kJXiMg)(1WYD6=ge z`fJZ4(oQ#VTRrieT>H|V#XSX$As>q-NXkAHu#PqINmmfsu#An_?>;!M*HPNHlqt4_ zUPj1{5zUkz#e1m${>pief|>9dlSB9Fpsd|AvuSEh$s-) z3VIWD|C34exP41xNcy||Q@xf0pk+Ya#*yDQd}cNv>6PuB*n=Ft<>G26jKU%@i0G*F zi7`+$0reh|NTe47eh6U^{pbL;R8SQJ`I2`Hkc7ZK01%pJNy}vhv2Nzjeaj@4Ua*}k zFn)7sr2c=ZtI{C#3`rNn*q?yL7cm=3`eb*G0d0Jl!B`w8W}^PHAV#|F1P;voPl<}d z0_vqM!iYt+QqDwm@W?wz?rI789VFT1!KNtyg3Lfid*tank1O`QdR2p#(@)of`4@19 zp+k{*bb#stNZ*p4!1%lK7A1~eF-$G8X;`|l0RWkd%!75$6YQnAWPgVOdvj-kL1 zq5S@>Oy&zq(}U+X$RT{uw)GP4P-1Ul-iOBox`$uv`y^sLq7KKffCF5}q zZaDbf(c!+~_u7Hu;T68B+^<8|rJv{S|92_HAeoEx=l0K_1Iy(fmA*|;T{hv(PbZ|q zeH+__^<8>(_t>DqWeq#UcfBV0GoNBx%FT|ri_PB;@v*M^@MGO2eCfzb4qi~y=j*p` z`lqO!UQ)gF?W5-}`OSFZA3VBuIsJm^;VxE^UL%5na8B9u*iC@9--pEslF_Ir_7U|RWM5XAHQ z)*JK+?(pxs{R%ISzLLh+T?y^@P{}3^bX7@rvxyOll0nh!CP|KM@9e(BB<;O~_eB4k zfGWWa*C1tYjH1$g3pNuU5{gz@Ip~H>D`N1(_m{r#`4@%c#8+VLj;+&r&)ku&42aoR zJh)f+)QWZRZqO=o>OWoO~c+VvQD|FMjX;uK%kr>WIBZ zLQ%x|=(owML@7_bv*Z#f%db{%vw+Qoul&p3oj_IYc36bV8&cv=D^BtAA*6JtIGQZY`HBw{XDyUQZ8zy=d(&%xLgjppIc&{ww(z9&t zv!T#?dAG9Q4Uo+Zfj-@*x1G%qPu|w)-qxUyFvq(VF51ObD)tm@m}JdIstyA2T~Dq1 z5{kkNkdKj*mtB~=dl~-y&+}{P|tB**?;W*lg39L?prqOBhHi{ z^9>>4ZETvWd)1o+`39-1gyP3TXZ#)Jmw|zF<6=H$?kNx4Fl|tAm3RZ6F&jQOh`ihV z{t|AcT=XxqY)~ik8p*$6OLnf7*(#x~(GlP4rFe4dTjVaa`@B%CpN{#ncByz}TX#PtA8bJ!KkNZ!_T1|ssC4Q<0m0SYlN7ZNIE4r51GVad#@4bGTfgN>accl44%uMt>24($Vfn5ids!U zjfk{-LQt;DihpM}uavv+d9_5`g1RTyu|f4}hCo91hKkqx>u(QzDQ=|KW+xPGXTQth z*Z&!g$dA^SrZwH_a=NlMWZd2CdPAwKdHiF)`>9wqXaO-16Fn{Nt@xRYFq}gqU+D&>_yF$wC_v+ZhUk@vWe&wl8LC>}$XMZTl zY1#NvxN)RX;hTaV%MJe#;>^lph0krP`_MIacPAGmB8*#B;>QjvhCUF-T`>yCNZ`$H zo*Ymr^r(I%I0Zeq85f5DL3J;GQ^JKubWK8kIyOyCb~)aAGXb;2T-vsSr@{Hs$?!)&!a9Zx;Lo#q(l6&<@DXvmA7afj#sB8QRmVO#Po zcj1&G2ppJ%p%>BOgOS#owF7=F?WQ!y*5mzOVYHwWny zi)MuE9Fvi#pq9o9XsG%eI9# z&G(Ys4YC3z6Yw1DWNVfL{Ox4<@Hz)gxJ~xA{}D#xWFah3PO(6|tqxq$q7(u(tNS<4 zOD7u1ma5%6@-KZX0-M1$^T1-JWbM-G6x)GB5BFa$fM)L^=~obWz8=ER^QJNc7Vh=Etf*MJQUp0z>@EoYy>4d+$@AdP1(?dVuG z{!_VH(=vNNo!ws+AG}N`lkqM&}E7! z?1%I}Z1D!L^VD3ThobfJ5iBLwsrH`7H82n{4mLvhK?W+_vCUp^N_@+R-eexYt^q-4 z4gWNaE!i43XYMdGQdP4&k3a+NU!sGI)F0M?Gs8FGu%mRI%nmZtaHnZf%|I~9Cl?`u z5pWF5dz%#%>$$Oe_shPK{J6NTVP)@sy4pQxL9dplr=Nz=YH70jr@V3Eq(P3h6K6U# zdll~u(3EF#U6yb+7s$R{XL#fJ4{+}jvn{Sl^SR1*FBQNxwe0^`&&PlJh?xGRO=;87 z?>CeYd$Gf77A0{jkLdVedP!4VZp%nmIrfzC(n1yhh7oT~K-$FlwiE)(j>-_%$`ofV}LpA$n z$?l2QBzLnSG+BRoc4-H$-@U#sj1jwiauj6<;-@AZcV<5l)-4jlRu3m5lN1v!z>ePJ z_pAqRi&gVOIT*bB&P1Oh3xM2o{J{kLtJ_#4H&mnDc#eE1ya6n=?Fl%s&-Fu<2n{4VbG;6Hh{wEPU%YpgJ8R6>MK2K$guq?LdF zb#UB5rC}_Y(Y`#L@k+kopYijyPnLSIQt|ZGdapGRG{tN*M^Yy5PXSDVlkkh z{2BJ-J!f`>sdHyFVjM|4FPQp&z#YW?#zcbZo&p<%bz;}=<@UI#nFpMIvhHZ+^lbYn zPq>@8NWna7+lArIu2r?1X5(X^AHG}NNGr$bbMX9ZQlZ!T~UaQYI) za5()Xa9Yk-{wV#qQv*NNk?9VHD&$QXz4enp5~cn0ft>Hcj>rnhWww?`_|wKA2)OMPr@&(SMTz@8EakZ_if)r1+7d$)+iJWmI_Biec+5TMzk^&d#nZ zQhR-iDHQ~(Wjwew&nFPidb}gzwN$5-JO;h+igGhPy{AoKrsd}PTb5A8aRME8xEsA8 zGnX6HuH~KV@e3Rp(fQexrhGyEjf=d1$1rWL0`56{oNGoSlUuO%{sJ=+;7ertb9o2e z``U`%qaS$QVEGRmdig9l$G=I1n%r8k6FFnIpQxJ`h4>VXy19FC#-nG{+US8@b}ULG zP~fa}6ZedqVr50)i3xnq9!1S4DdLeO9(T|{5b@n;FN_Msg8F22&F~_vCNYV7f0mx> z&E@Tn0EdevROrMGfqct0;~#4zEU_SaYhcG@W!0>@+~6gyeL2dfIa@bp9B_iYXSORo zsEINIdK9VPJ&pwi(eF)mYLUHD!uoZn&6lMzS<5lgJEjPy8aYAklK)I$ju~s)Z?bQO zrpHAAnc$xtxj5gUy@$98e@3QZ{h4ccuxgTWa@3!C1 z3||d3$giOSc_40a-)a09EPn+^?1gT40l|PX0VVf=7WNz`cH2`A2oX&E?FmZwX0BOJ zWdaQZ27Ucty#Rlf0^YN;;j{b*X?c=U9DVB7(=^fu76Dxt@Y-EVfOcqOiHf>{|Kl_5 zDJ;NDx(Hao^Yg>+Ap7?cjW!o>*ANJ(Cv3TJyS&elwPS=#C~wl@0WQlzvA&nuCNz%FC6>0BO&Rr1fVFVewNsv$fvs)~WQ2C&d)miW`P_GF8w zThbe=fp-x{@J5&4AI59{*C`c@dJAbGWud%}y!29*6ag{kKJ43Q_NyA-;n+W=_h~8_ zKciCW{`L0Wz#7Crvko$k&XsbK%Z-D16&m1IbMlI*tzc)^?U zYa5-|Vy9_jZ~YYQZ|P-j+yDiVw~Ak#p#o z^-?ZqP7~0Ssf@|Nac2jKm(v*k@hZppe0k*!M4*Amk_M2X8zX-I4*3%MX$nc_s{?1y z)L{7~wn32Na`yXosiQG-jB!vl4FIMnr%J{-*bJUrI+~FA${lb3e+EGY%3hv^CZXc; zNYfsL-)L~?M8pmpcEKbX+br`D;sS?iuWkh;AQ*t7pT{7EvARd06PuSn(2irUTfkYx3NO*nDFzYof|Q1$Yrl$mi?CVsY-##BLgS9PB_!E+ z84W^UvZGUYCuJ&~T3pG0TDkM@$rA6j9c^;XkV?s}!q&Rxz0w}$X_kRJR=P8~y8~|c zZQG)&l%H7sB)1mfewXJbQL~F_#eKEkWKC*Lajj&B8FutgYRA3hm+$xmEWBFMy5Aq_ zSJ&3?O50d&_mU?>U6kjyso7F6s$diC_qBJ~f{FHc)#cFgsOY-hbFbX5?#Z6C8|1r6 z!@f&U%FL5cW#oPkE1(4iu&{lj#(58*p@B!&AQxPnQ<|RGXXa`e5(Ywm>~su~*mx@j zA&QBgy&)iY)y+HI+UFhr^pUm)2P%&@t&%M@;)ldoK+bKK0kiNvh$LJ~l}*@F3cRxH zobg5|X|l+@m*;hbsHd?HOAC_%oYM>S9Fkg-YKnUE^jA3vv4PNZ{+ zkUB1S#7;SHv5>VOeVeda8C zY39kUdrq9;)JzLLb+uglr7_KpIGk#^%B?&BlChv%`M{iJ*jKeb`yvCKgKD?3In~8o zC`#S36C@;?UT`<9#5^B`6fISbGyR&7A5_B6b4lgelxf#m^R~TB#0-Bs{{8Z6#-x7(pD=s;8NoLs#kw$b z!?Y+p%{@fipym57CZtUK*QPkpFYwp}F0IpxyF(zp;;j6LW$&are81j7t9!Xu@&XYm zz?gdrk#>q>*CKy}6Ge($-7hhbtacW;w1uM-oqRvf)vvI)7u2R{tbivvS8p^osR*N= z9xBD#lc9ni;W;Sp@~9=gT`PqRjIP;Pk5e z4xr(dqek%eSBWv@xD8aXYAw0MhYUuP*nrvo+hytcuSWsc3AT~`quU5|ya*1atkt@l zGe*!9)OJF^<<9Dsgu#XD@caT>gBM{ve-Ui!@KBViG`{m*R% z_awmfuXy|8juI+-F%Gs0AmvH&=EI*#SLg?=Sw$1{PB9pn9ULtNa`oxVjL=|~I>5o? z%uaH$hn3yWo#(gbN83T+s{ogu#NGKOGXL5Rw-ECTRlS=Yvpw&A4qz&HM^tV^jtsbd z{v0>R`R60-bNGQX9&Mco)vnvGk8?r?xizf1-#7g6EP8Gc{Rwt`xm_>+*BA@pd7tlh zG!6V2g;PK0)q2Kl4!@TqDMZK*m!4mw5i7S$?#Qw2QR=G| z@93j0p@W00SmDrNjmjbQZ~Y9C>91bUOk;)ss7s z%fk$b%Xy1^&2eM(miJh#;;J$WmI8}s+6-fuD?fsSs;Pg>JI<4O|C>9pw0}(b0Y8GnLv&{@yDytV`CGfu(Zs{ zA5kMGMp&~$Htjp;J?5!B-GF{&50{lY!AxCSUgF-bNJXcQ!ZJ`(1$hxvyHb|eC?@{Z z-%qlZnQtW$x*kutU*PWO^~H(A{hEgwRn{6v+T`N{iEmv-UwYug6G3!@r_BHLxtA_0 zRGN691_JK>0kjFV{PPIM4dw#})Z{xz+Fh~G9DV|RKQnHHd+9-?*S}jWdP`CVP&lbC zzC;BtCr2qNv-~DnU{AI-2{DPAMy=}o8nLuCX+uWwQG!dtMgO7cyJi<=plVH=*_&Zs zk$jg3M1g5H}&}qKEsRqJAD4Ka7BQi9@=(+`<;_YdmsME3yh&c zku`%;qJK)2l(08<3ej6dQBLq{}>hH-wd-f z5fqq>5n7(f31!?7;YSO+&>HoJW2`AR~6Uk)%w0KA+lr9}KY|sC)5Lh>Ui(&b)<7Ir(d=}QlYE;F(XE_pf z?d+BU4H^N!+_9kH8>CrS+?(RUwsx9qd>Etp$dNs<=I#*{Le~U+irq95pbq%%Dv*UQ zlxufnxH8{Quk&j8ea^;j#EIfgkl;?9s7%U~qdrv~v|Y(PS#@nS)f9DQjw{QBx(5?d z{JiulEWIhmP3mP6w7>_|2vuFmlT4PsSA1L}~XPQum zcCdpCm$=xvzO=W#V3mrmgK81VFftW))n56ep4aX+zTsyT*<^=Pmz@n9oq=GVuOBhh zLp=mOupHNS&Tc4@H*xBF9;NJ`CyWrEpeAYf&|76QxJ790s|S0qEx$v>Q3S$ywDbKo zXLdQoI>l4b6vhTVn-Slf0RkaLY*Gq#)#1ls2n^(}82W?T4CW7BqX8<%R=#b5f@EBPizdu3Dz6mV zr+EE`xL|OSK9!*iC?n#FMrdPpmy)y(sJrMfkOdtuJqe4!B(`ZQWa4AiN!Y9CkJl_C zUk&zcEKu*edO#M8o5|0!St4(G_#of1OG6kwye6)gy__93(F?A-YT~)gkAGKC z5}Iq+M~850yxC(RiV_+-oUMB+2h{n&O#I}paH{lN!A$C!&d-><2=seSHrBD>$49u| z&mOlcKE)>JT>kmzCf94N8%gYmkGCP1=5vv?%dFy8=#7){Oc2`;pKltRV*!5V2hccN z2owJwem_)Zq+{>?lF9a6y#12XlK0o+&_Wl zu=(Xl{JeluIwnnXpu5K|P49SiGi;AYAJr|NEUWu{JH^-CM+yrDrqHq+Q;>lwk{Y2gGvYGi+4PA5dheh@0h;#>Vn>f#k2`3cDT_BKK}y> zu{5OAx18V?yHDxve$Sa)5&ElTH3&GF=T^<8L!G~hzChBx0?UroLWjzzS^AoLU zq5a@nqT-){Le)djqNp#HS`po zxb#-Ijym?dyMG-YY%_NsT2X|Jsq`85d6pRoYa;|QD(PSXW zTvLTLi5JB+w!Vns|8bV=pUz~JK+!P4-9J_R)<%27B)8Cr&r)TnI}sbLI?bJVm5rKT zhCzxX(Or@h`>V;W`anna8r+!#F!4^=aeU!X% zs0z)iZ;%sV5LceqST{b3@41D@6|1vD8I{MFp!m1Lka899zHPr@-WEYnwb#hNtJ!|=hyZ(hULMG`$V2~q2`7M)Caq>&>>cYClE9NVp8IYDaE zC(qoC$Fpr4q2t9r4^^dZkX$9NEkrPbkfdl3T5?n-(PSAQ0=*m_yY{J~lfilA-FFaO zFT_8?fH!IJJ$#zFW22MH{)M60i1Y_{pEJ%2gKOlBu*2yaG(e|KsDy5k!0*F6EaBhk zDsmZqQETVinarhi4S^wle|84u_J=QuAuz-i-ZPTpssv}cQ>Qh!FDj1(q3^xetz(-q z+v`BykhWwmh_<6Ro4;>kLZ-9tpXcLAKcH~hU~YiUyl4W(jC$!|d%4#o3({`}GEZA| z<|g_ob4KS#I87bTb|k-BX3nOU5#NfT@%LkQoqybLhOTi1hTQA%f~x5e53@*Y8HTAX z&Gtp&eH(etI}}HTWh&oSo|9PM?n)}kILZ{~=SnnY31wowZ9i^K{}#D7#B^xwASsxy zleBnhDGh3TX6b7Eh7(y39|?|&N-2Eo=Wc^8b^F4W%^w7Rov?1jm;cT2&iO5O`LHUQyr}QNU(DPU=>B#wC@gPEC zor4Cm;VL3uopq9nX+_yldsKsfd9@_$gk#jNL(2d+vamNOJ1vtSCnbQVU5c>>yT>es%5~ z0e8rTt^r3$k7YZuYa)d8*7qEB-Ml0)KHg_h(`W0iwr^ySO}G%>)5>j{6)WO6M8U$TA^n~Td2!>_ zxyqKF=nUk>Z;yynwl>=z?mqf9B7+Or?ibu5aA>|hPDbRLzXeNqu4H!`IR&S2=_C!w zGcAe@F_x30&c>K~6CX9pJsZZwG|!!e9&}N*aZem=sOKD5)6c#kVY|{iTvR+B&@*`z zRFHwIu@;3V@dx30a<99ZTniuj%1BPO?0;-kkhqFX=%tfizhV$o54(tgG{P*U+cZ_= zrj#VUmo1W|{E%~z1#$@A?Xc|TEzr4`FiLQdMV_~--l)^ue$5zJ=B#X0Jo_cCwID93sL2M~e|9pBHreC#aiTbG-kO394N$_Vvu{%&nkU~Y z%ur{sewm2-bkf4LQO^m=vD>_2A7HIIu4+tRI+RKMJ*7Z{34T%IJbLULqB@)eLA>!6 z00ylKSXFngm(giduX+U$X;MI`a0?AR2k_u-I)W%G`MJ9DmkuprDwck9?o(}v_LUsh zPM9zpbP``W_XD!G{eJJ_do>P;cI5R=;b8(Ympa}9B-rm0Wtq))c1w?Nl!rS-PHPKl zVN<&4<@#TJ2-iGv`7V2`yd$(pB$dbJrHhDjwoHEV*f{x(o`>_BFx5h?Z^L?$(95{~ znosPWEJ6i&mp`kXu8#c6^xQR_qT%j9OLW(?A=MR;JvZF+wmDsW?}afXd|Xu>n0kFY zLFpmT&6jfGaMi-B4Y`=6?9(_l+{4``b!n=T^_Cl~mp_{N@9jbz)2V!Sd91pxx1GW> z)M%LhLzbMMJ!^Hg@3&!58m%u*z35u{EEK4YZfAMG4xpDK!;WwsS%D{Uo)^~jv9r%S zghxy&DqgroY>l~P?i~%ZS2w9?aJrH1&T}_Y!%Ha6axAw!WqRopJXmBp~ZHMU#>L2>MJn z%J-k*2c%6G(a|}%Mmn39)f~)v+GqQeKIa~W2jPu0^uF=;DoEdKLnU?S_N~~n8~$iN z|MCjKf{d8_50R8EU*ATy8ECRqV>e$iL-F zc2Ly78GB)rZ-(p9+86D|3`{E$kFhmu2}fu>--g{1?)#|?kml`HC_J+XrU=?JxzP4| zq0ZHvj4Q>w(J?W{Y-$$l!15O#GV0EQt^oj60}L35f`v2Rm2N?5rfwD#Y}AxRZ+kUM zuQ->UR2C4|iO#q_zXnb)+guW==hQtNtdJ)4F^3`7ZFt-NW-ZpyD|y=M@58h=>v!NhV?KZ+X=>ZRdZp$Y z>*Sj+cmAn~oWiMXg=x?3i%x;KkfY{pAN~*ao{?WsXTud*#2=L^RZzy z^aL#g#FK_U4;DZvEi!|%I^^OZ?yy|Lc%0lqO*(8?KinwHs_UG=9d6Ueuyu@Ftk1%p zHV@U!{tvIdh!Cx4Dn0tyQ@@d2sgd>WBdqq23z!{=D>o6(>)0=eCd67ZA987-f{*h8 zW3n8#kp%I90^2TMt2c7Q-yVCD3;&f!v^zAN^_*YiQUX&QblelCAm9UK&i+~Pv2lP* z8s6Wem}$^TG{N-dM~sYa6I4qbAUzmz>bM5z6@1h`qzL(a#;)N%K+AGKK?ct)Po7l$ ztwR`fbZG^`Hi*dES=Ep-w@eWU7J{>3nFsq@h?az5})ppzUWt<#>nVSP@a`NzU zX|-jE8@#jd>lSlrpC-aHnhW^2=DTbU52)!oRW^4xCx!YJWQWNL42e4`j=>)C1HUYE z1zKhAK7C*L;B;00@vvKaVX}u%=6lW?D|AYVFt!AJzPa`6$BrkDbm6YHf=80Oy1ViSLx z30nO1oo6vgb<6)Ab)Ooy^XP$v`jCc-&X}m9Y^`@*%EQL6l$W zGYM5qBoglLG$vLZTPXRDmnIP=qU<7q{_!sjObC&`_7O4?sfIc#T~3-3VN_c>+5d>o z!A(Rt%Z%v>XwL8LoGB3BNHW6^o1Mao&!yhUJ#ag3Ult8&I zyYL!3Y-F_w_L}_pdZN_?-**tA1xAw*C8qH!$TZjZNiM%ZY$_U9Ew9@KSA?_lHoJhQ z+Q!V9#CHyUKJMr3aoz6!u*=`&aQOcNFk(S4aS(z7cjsu{TU8cmJyH)h-U|>FH0)!W zurX(^mBRLbwyQgPO8~{ZQx$O){yB(nuMR5q^b!FCsoTtXpuA#|Ru*db`S(J}Txu49 zDiFB-0#`}#YdXN#K5#|AtB3Qk=Y2()14v&*Auh_?r24g3%N#wFx|+v4794n$t2)HKlaLh;e*uNN1n3i1i1%q|Mc(C^!&(P!}A%&QsO@+ME(0l;|ml9 zh?rm?S9Es@VoB8g?l47-tJNw@hRY*=4)L>|F_sgV!W^;t&CU8++)r(LHn1WmH}_ zk|}|Z<~fk8`ot=2jfKVasvU>4XX1O+bU(4q&scfMQ;$BjjMpV?{`pMRjJNN{=^j)0 zS!c-=-RT{TSRFsEKpULqSMf_jtUUzR)!`=Op>~mfeskZAU5d<<)tFcdtQ#6Q|BeZH zeMe}un0t&@q>aDnzEG}qX@#h@iHf_97}Awu(rjRWwBXK^^@Mz zF#X6ny3_iCLkM4nT7L3iQ1WQL!Yz|JAV)kytpVCbS_NTItjp}P-l^aMdTDzA3x zEo^%SMl0IZK%XfpOGM zZY<8sajPaj&Nj2Tvz@ZB0p@N>w3mJ%-X5*r8+}^vebK~$R^NIDW=7h@=ge};5&aaq zHnJDsichM4qsN3?jmQ20npyJH{Z+><`MU>_jGGwuX^wae#!s4ZDTCRIq{C4%Nv~Fe zEnKRLa<;Ya;i!eb(7>C3^xXxG?RYHB$Bx6B(@;zfldMSSF+)ow=|x)AMY!3~jSJql*23kxZ z=Fb~OD|pow2NTps5vSU=a7OONoQAKmk$+vNY&^747*@4klJwX&?PKceGt|4akOu;R zrCX{jF8yqOyQY~L6Rajow}vvS+J;3cmGdVerlFFJuzUbFwd;T<`<}nrq$UKU*Ra?= zLBQU6!5&B^-*cFRopi(8xU<83IZvg(r0%*+LI{SH0dx)*HnJB@L~x=5O*|fYyz1eS zC`{xpK!q}XnglANh~1L*OLsWE?t8wT&w-BoI9lzJZnZ-(R}$_ZChvT6p2}pW`wvGl zkxceOzlzuBPUYoPvx8`IfCp}fghCi`2Y?>P>{Sx~Bo)P3C@PsoLiz(N9o||GKAY&{ zH4deBLltM%*90eV#-D3Rnke;%;Bz4QQ}^N-m_%!XLg?l+&LLB+hJARM9I?1t@)?F8 zMo;7PO{hvDH`&y<=5w;@Ve1n1#OrW5d#>XPH6`fESRmb4h+{?ewr`a60X-;$F0vjY z^9-+ImvaGI3$Nx~dRS?}kdc4BO#1aQdiFSbzaGqh_;}x=i6p`Yw2kwS$&_5!cdDdpAIf4FMt{z%}CYAsx#cFE)x5n6KKl}{(@0r?^ zT;kHCgx}WIuZ6BSp=+QnCg^(ToFzZHo7CUY#>F$rA&S!hS;+?Kr*}MMmA60w0Xzc< z1}K~+Lp^8agn>h4NY19d`}8@)75#S<@Vkpb4N&P%X)46LrkN*e5qZYW>$wBb&2O_W z6Stbku$niu=3gxuz4;NR`emSO+Aa;b_uRG$dwHVo(A$P2MSaiyL51SHrKO=RKrSt zwB!r7;DaCca2}k0zN+Oeze!J9S@x~xGTW^MqJN>yiQLWnyg=7}{M%>v2ge888T1ZA zWL2v>U5G-D+mf2sg{r^c7l(r+`gtOk#Xqp$@vi;*qs2fy&QDP5L?Td}WjgQ_9Vl^V z&iXo4wIszr>!84EZ5HA2p@V%oD|$d>Z5SBK%s%py>HvkAYa`cHM{}OXF9-qBb(<08YD`;0lYxh% z{1dK|{)z*NWY1FCZ#lyU>Mo1 zopHb_*&H@)hk5xYsr4py*FKgu%&+frj-Azxs!91nRX`QlSBu#n3XgLt!d6#`7 zMdt(S0^Hg5{g#MBoP#Mc)LAm&hn?t5einAG_r~MBXD(r>ayS^eRkIc}tnaUUBhr0u zeT*l%`;bNtSxH9Wc`jO+<_zFi`ZojZU^1~;;0_*YYxaXLwhI8tXidM6;U)^6LXrh;P8{PG@Vk88sSX$5^|3!~ z>!2LL`}Yu-7B&R$i{QL8g4-|UOQMrmDIQ3~XHwflq0gpcd}xTkn8 zm?SoPD@a1K`Tj>Q8tPp%UCU+O8xQ2HQMHBMHzo{0H+44+7x^>*gQzoGZ z#Xj3N`yTNcEM`M;8T+TTnxF$B?jY2bJ{|d8g%?xDl^ry?oLS%W4J~A!^lhAwp)eOB zflJ-I%Ke38wLQtE_DrM-VsC)kG|}yRDL#m)KK%4DXG|Y&ZYOii%X4So)jO6b)Zb;2 z6)`iJ<$c>pbbg1lF>UsXlq(3C^^aTOtMs|Ppxw=jSg(ifD!QNh7d_>DqC`JK-FINs zbqX?Xj4MM;P;RFJKT2W}$|D0uBwk3`YkY~WPp@)eb7C%rYlvoX37{ir`~*iqq;gFbnD}yhZ+3jjLOQ1NZhq|DL?G zUxCy>a(DsT@;w2DXD;jXE6aP@jdHpoD~^ZdBGWs~Qcbsf8#<7Rz}Fq2Dsa(fqpk1z zTxfWsoFAp;-&wWU61CC@>2Gr1NF`1!lNAa1-QPqd4PTk`CU!rfe?B!&AO4;*rFH`^ zAN*nGc)3$Jst~rkP{UZ5hyjvsKFy#QX+A$(jO{ijX)r+feDuGpfCAJ#h zj(}_9!9Po24v)V0S=9sbH9GT?6h>q;n7Oo*C?{8{9p=EOh&yo5egJLDk%>w<7rZ?9a&A?qR)S<+o6ei8Roa- zxtmikZ@Lon%w#UUiHAUWbpM;ozah5$P@$(!GQp_XF0H`dU*(>n3ffoqSf7PB_{Qp? zXEafAu&E7MoyV-b14}q5MU#JO`sEJRo48aypu>x{qr4&k3LQZbQ8V$&Qq3uf* zcQJMF-r0SifHBi?EjY>W;Dv#Y975G^;X1i@g|be|l9@p+6fyq@5<4{ihyp>a27lkt z=8ab0yVf=#`f}nc!0lV2J8}*i4zlR*{OfTuZqo~w$`gQf#~ix%01S1inknMi{6@kD zPm34D_O40+Tr*WJDC#|?n8*6nu8#8fhgceh{4+{$X@|AQB6!|8?j8(LEo5QWV%j(n z{A(ZpelO_~@Ao)Zg)b4cpsQvJ593Y#;rpc3`slJP zmA9Yxa#XIb%DC@;J)iU^FtFlW&dj38!Fvk^Oo{Jrd&TihQKj1IV5;K{_n#;;hN(PD zmc9rdRcP61H%UJ4+ad`3-%kbeZV=BS(vAYS5K*zm`GGKH-nqtCs08(bOg2qd0ebcVvOtlZ3S{V9Zvz*JYp(N&fGzVZRKLvu!pa`7#BJEncv*%kYilj{xhq8_$h zN$RZM2gKHc1OPS#UYnp73sTYkr&$V&wK-}ite2?KF9HxPMui@_kFFG-0_t<*)A%8# zTGua{1PUypWlwTF-(zN%57VHR91}KWnIB!ey3Dj?Ey`TnM6y6(zzbOvtQ&^i#Isog zl;j@zYBdxI`jG$SzGMP<9kHfTne+&CY+>)2f5or{`uMv)%#s`A6l|mlKf?M7g>L`O zAe@Ik3&oB4uu7!TB6F=KkdwH}%kFCK=T<~Xqxtv{pwvD8$xncqwsXEh!$KY=;@&8g z`mZ9|H<&h}z(pIr8`NhMlBILf$>d+k_%IQ zOX0HxVO(cJc_jnG>tg*PB7`aD=%kU^e0Em*-t?tp0==W+=GPw4_0kkst#h0>hxyh% zN6W(lfNy;tP+-u#ta0vMY>rIwMAVHn<8rm|oVsc$!&@fDQ$vq;IF}WcMs%`CUHt1# z_7cJ=r;~=Zp1&?xrG5+)xoqF}vFY(5li&G2*s(lKxAA=7ISd|A&5dHpEp96Pey;Lb zK>qA3cT~edG}=|mAt;lM>2}P6cR1b72;jZD2av9BxDx-zRH;T%#Hn*_k z$!bxzV{`al^`3GaP>k!ANAP#wFSoJcSX(l8GN!SStTteC1bc7j(5Kc8CXbHR3PamTzTd#9H`EWY2*g7BW9p1--I;Z{k*jK*k4GX!jj6P^M`XaP(w^~`l(7Ld^da` z+XN=$?x)k~$P)8vs;(c`Z@VFn~oEbefkG6o( z#{Ed{+9Vf^KwgC_y5;QQOGsDi85z7ZvC7mDUVI7O^+nAU3U_Z8dp9>}kC$KtCWYpk z^4{zyNaxesoWz^l9-W;{(m~Hi>dWu0!OLm3OW(E6Vr~N@P1-wkS93twFWpm4K@``c z#JKmZN;~;FDtPGa{pTy17Xido=20|e5?2Ql#G0)D(GO57_fCCwGt|!~HB4;=ht;R5 zhh}c3Z-s%&cfi46s&B59_bDYJEy%boU~ujp1=?kzI0+Q#Kq+~u1D)>D@rQ(bY zZ9k(t+9M(xs}+;H{O&YRl08)VDffllXthrS1{r(xx4DeGtNV`&ibFkv_fZ|liwoSK z1Czx9-KSjK-Kv0i``x<;=Zv^LPqH6M{Cywh>`;@9oM_YKg~z)g=&nr8Y3TZ&`g4fj z3fv+)tSRV^scrTK!Zx%QS(QSafxm4ge zfT;%K>=j^(=s#&?%ZLfTctneu%p8f>_{bE=I|Iqx@h+wVro+FTR=!ULKS^_3?z(*;w2dFpL#lzUD5Af1A*Wbgv3w>iSnhH=XCg#8zxFIG!@KO5Z_uTf!nv zhnerLJE!a^(iu#xo8QLOd_De&=MnMD`Fa4QkI)trXrbm4g^X2nPYL+P4~ZwK&KTSIiN7GT@XjU zjyLh5K7fkLlrXu{Pj?kVBnllwq>ZS)n23%TxnCrmw2CUEwiM?HuJu3DDILC&9rV!5 zdX+x^AxlO+o~g_1-&D8?a0DNw20vCN0**E1bgOFo`(Plm5lgMqM6!$2idcusXtc(b zu`6TI`tO%vi)E!VBZB=7G@X5-eHY-(3`&N&lR;tUqsjGXF)}57O-+VIQiGg92NZxZ z6EXa;R5Snbb{6`?xzelOm%6T-3Bpnwnt+wq{p;uM^DBSdl7n~hbF^ONgBF8}f5S}{ zF2GfHx7K3I-F-|XHl$nqN#s zMm}3v9vx#v)9{K%jhbWLfV+Uob!@#u=ZYk#M$j7fGy zyPUMRJ?R6>^bnz0x=$m$KXN9_F1^wT>?I&Iw>=zq8Zt+~nD!bI4|Qk&yctY66cknp z`vYDp{}9sYcOXOMQX!4>DWkLBg%p#74R6unFK&kg_iLWl#r|2$19yZ=p}%-x&!XPW zKzY@;Zs66+zAIB>GYx2n(IEZ_;wR17>%Z;!*5^h_X#1KnM+PcfTQ6#$y4Hw)+kZgO9TXSs+@>kY6sz2lqm%2$Cv%9799PWPhtRpg-pBVv<7)d2+(+7V#W+dOD2 zufQGnw-lKumhCUVi#xk%I(z6Q$4)q_F0&JU8S`c?+Bf7I?StT=p(Oi;g4Cy&Bi1bh zc>ck&ET#GO3+xZ6+ztgf3J4gEkMloUUv-bXal-?ywsaSf-~~G;$qs^8x|=qXh&La6 z=8vQTV9GEgM#gr*%BAfytQe#?;R)KWkDB0iI4}i$S&K$I?=r84N`}k-oQS)OxP3Jf zU?d4N03bxn;Dqxnzjyz_YVFyPA3mu8K68vL%O_YiL%zdTmE5yX*!FpZGZXI%?kCdH zU;j&lT{MXUGO7DSA0WbezP!A1Wt11@4wl#0GR#lnKp5%JUgoTEr=_KGMk*U;{w|s8tv8oe?av@AgRvX2azg7j@Tp) z)v)`H2XxTK$6DtG!PX1xMb`TpIMdcg%09w$b97O;@5olE5R*HiGF?BWaW-?VUtm3g zyt2}J&7J-qp>Rx3vi0X!DX=nWnmQ-bHs(4)QI2z(dgXvZE{Ew)!=Lz9RC>)w=0eXx z*O>!ofvdE@`U0HIizlO@w|Ri@VEq7jRBRIycpRt2G&?`I!R1I)_#bJv83wvIwRB;u z*#dV`iuZ!Y>MT4TpSb|P2-%2Z?M!i{<&G$Oi1$8<-1{0FgFJp1I?hXy5!VoSJwOQA z`9X%ZzEKm(;{w4LX2oCGllS zpDT-|CAPy+kCMA@(JDzGS)4|oKp%SUfm5XQCU-aT_Q!?u<$p%SIHRa%U+b=K%GxFy zaE<%4Q|W#?6z=;I%2fRf8J1OaA&!AzmZPgje>W$`qUY6vzTyK8=>%%{0koZ?2)6zQ zM7@UWK7L%iJntXDRDC3UETS4SzuI??fW-WBCpdB7D)SGZa{@`KLz92erCm}1UNCh4 zJ+R!GQMVAq`ASV_THT+8LxOH%aEfm#`al*SB8R!;+#{yrucX*Eor`~RtqhY%D9+=D z(|3}=zah)R>gP{_aiv$GLoiZ!9&Zhi#$(#?f9#uen5XPui0jL0l>(`veJ?>1eq=q2)O2fZ@5ii^#IDDAzU!yW+44)` z@ANpw#9)O>zp0Um6hp(Mh0{2@el51^SViKkR<3KvW?xXeK@WlGA$_ z3RA}CPDsCB;AWQaah^l&4I?KqcifEE;n~dpkdR|x)s<GAGEU+uwa~m`jZo0}`HRZL2JwvK;XzNePh8`WJzMgj6dxi9 z>6KPFppZWS`OPxlHzj{}!oZrBvZRRcb{1@d%Y0oMU7sBioOhdLs<52s=W_I zT(R+30gQIDDPiux*OZjW+dlx9GlNrd_X1IW9PC|hA)#BU7Fst%maqav1b?{Kt#ET~ z64%bf*U0H53c324ixJUGl!?krS>-W%L7R6&zI8{br44CxvHOY>Q}Vy7Vtv#-;aYcv zOh>(6p0kzPU9My*2xA-}Aa679YCcK)KpdsHRZMlYB4OF#X;1laN6Zg8<-W8Jj3S;d zHT1}D_4d7n>K^XblH{5PZ1yZK)r9ZA{qMTby9&+9$%w;Zc%+%HKJNUO7Wzm&-pcTL zXA!V6M8{t5?cr&m6rRML(6=pwr4mOf)a5On{D6c|&NWK$oqPI^`3V5`vZHQJj;5fy z+YyIHkQSZhWY?vPOzAcG)_=yTG7v`VJ1Q)yQV7VQK)fE-@CA|b*2vwDc_+5Cw8n{s zs#xu3{emtBP#^8_|An}kk+~pux#RrjTza4wiaySOheO(k?e&PALPJE<$-=2wR^-KA zE%DPg?pH76pa2(9LuEU>T}+Llw-0HO>h?8FtB&7TzCEeY9?XO(UMM4#vwUd&Iu%cp zBp}tB=JYGQB!Ox(5bbx3ibPsm5F%YvTT-p8eSlWT*m%LA*IVRdy7MGH-~La-Z*D=i zO7qmt1j5J1NRPeZ1vfdoT(YM-7QseI>LcH;rb1VZqWr=6EPANjy=qBo?rI@9nI1>I7F#mxaH$@!VU(nM zC-OAeIhh`Wy>Ms9VyFRD-8_9-96R2osrwnOn0GluC(a*znW{DK$(!$u%4Gl-r;l3z zqkB$fMx$xV3N#os)hQ4Aw0O=zZrBT(^@+XXP}0HYG(zci56t2czPt0I%5l)bb?Xyze~~8t)=`=x(#|=E!Os{-ZD_E7S-rP zJzn(N<=Vwo;+c$GZEi_d&r)BTqO9VM47M`V9B*ro^F5%RcfUaB7Rrg&KD|96qieJS z(-6+o?9FdEmQy}%;fSR6kalf}UD8Rn3Z7{=F};fq9f+c=OnKD-dqa9nRI<0=pgi0{ zYgJ|o#K@))Za>t?6Y%zHfA{HwC|FMCT?m(|NpxZ{j**uAI2N{RMhmar|8oGH59m|M z2)cPAc+)Mb(UQHYoNXyqBfHy3%J75VJHbw-J#lp#UdkVT_6JtBVPS2CcOH+c$cYsk zK{zI*-@}H{5-Fz*Rmq;4{Z9SPJ;MEqSQ2Y%i7l{;V(RL|`IN=<{EnZ9&B2r}96t4^u0)ei=KnE) ze$DgTMjq92cwWO-Ve;Nu{43o|2O)8xi*;)@W`w=rFDBe^bMR}-5eVY9i0NxDV}_RU zY@&ffl|y?=vGT#UAE;a9thA^1&K>)d->1IpG`<`|`&c*2TCy1_qxW6W1f(qnh+^$J z)k=JY-5(8&SF&tyHyLpOYO1KjM_9@D9&30u+2JzSpg6v80c*o*CsBF2x%`6f4eaIm z*1M94z7}f_RXmOIc&{Y;PXb8B>ZnSAo8DB7ZI4|BolacVQ9$i@NB$M$;=rp4A)}kc zV5MmsOvF);Xi0}`W;@yUararI&wVucKvHI!I`$?4cmMH{+5Y@ZXXX8XKT86PfHeAW zK_i1;BFX-I>A4@!oH@jWy%s05YAQQMv(WCHJ81;=#jKN7`rHDiwJ4o}7wOHXoB6K; z;8A(!(RG@Fq^@84=kH@v4k&IQbIr-w4o7rJc2fReP6eX(7dV1(A$v5UMs!|v{}d*fOu?8ajc)r7(oW|6zg|G}51X~< zqOtad(LAdm6v zO39_0D4cn$3s_{+vdhJ9P!BLeas=jx#EeKtu)ijCrO8nqh415Ah`VU}hll}7;wB6C zoba?zVxEwN9}YOi@k^BlD#1HdaM6VO_}H%{|enrSWDg zdv2Fuh2pc{dJ>)OrH zFR*i4eqONj_>AJ&i}1d-J`7~zEUo511HX;Eh_33HhjsNY!1h?@Z~0kioP#0gxOj6HEMdNfSf(Bx9$#&t%hgztrOu6jM8B5 z%hM~Ak1ljU`Qr52=cI=@-(r}mt2;K5j;SP;>IJHt zt+Y+9hmR>*gzNh2wmkA2@{Vt3^}gRH+o$>+tm)!kpG8_8YYJa(m*Y~Yx-9kOfVyu_ zY#yF)`eA{)9d9t9Skk)NgKqvSZIOvjLzfNkbV-9;*Attng2H=tBY6i=4Gl6qJB=ij zYa$)O>I`NF&}b@wu>lnx{bcHla3aiRsdJq`k6W`l-?7da%1rdUT9~E7NhgnC-C$SVK1*`|$L>T$QCf5rjGCxsj50i59f5(QH zV3ZDk**yD!44h@S{y{5u|7?9{TW@*7BFirWJ&`9LcD$p|gTnk%F3H@n$>7ek0Hzbv z*1JVsWbl%Fo;$N;)#151-`nL**CN(AzL*d=DItTgQ|EK^z{bOtOO@Ya2fzQpl@s?$ z=gCgK(INR)FS3|D>X8FdxO=ApJRqRz1Ec|p?#AJ%`ATYxcLHAuTw0 zgmnvd69BQqvJAMmAN&nHkxLX}*8{dbFU#U*xbCAM2NW*^WHT&RTc2~Z9na-Wo+FlZ zkPd->`ZD}4aqnHBnfJ%O%&;;)ZfCO99Z7a;zIsl@QsJxA2=5iJ8ey7x${DvE_M9Nz z_#f7|vW0tyy*9;`=zl;Vge6(j#~pe5*>iV(F8cwLurrk+gG4*K78;N;`?(90x4a9B zyzwCcm+RZCN4|CbI8)Gahe`5L=4p4%{BJ4Qd-d%=YooZ-kI~hSgotIAV`}%UGDMB$ zfpQ~G0TnDFW!2IEom;-;`LkP1)%@;GSnC(IM_>gbSdMcj3X$vz6*ZdWYC-3y@*+OZ za*sA?YUsZM+kqWyQrdyK7JDS{ZXm>VA@0Ay-2c&Z)^Sbt@88}WI6)l>A}S+9kS?iF z8!9RtA}J+GH%Qk+5K&4%LWLnx(g-Ns-O?$|Xc#bJ)bGRneV+fk|G9m^YrDM8^L)RL z<8L;&A_!bSb!bR5LFa4lY@9szPzatYju(F5902>0NHq;{Zi-J2_pahLdeOsPa$z6q z{K^3U0!}C^MmI$pGI3OVlojG(8_ET&YXK z?pVAph#53Cu_`zOT#5L18=@B^I(tCgWS~H95}iR9=aiou>~6hb#Lt*&DilyO{q8Gf z+~74w=*YYy70t_ovFEHJQf@uB=S#N-3YH`zOWc0nkEHKEt+(l?ZU6oo@je9R>aK5b zp!J1MvgL~H<$P81Ro03x%Te;B3$AiRk5hrYuPus)(?`MIMmL_|EpW}YTdXoJ<+NqK z-mOYfvyN{Eph0EZr4L5VvnG6$vg`l(vhUR7<-r=A62JfDF)?ZNhoZMPBuWq5ZrVMT zjh6dHZ%b$Wr(GkCPJl?}8rz>W+KS7+WmlZ4*>(OQSvQr=Dh_e3&V+v*+Kzhq7+>0M zU_sv!Yg*2gyR3ibkc+o(*JRJ;t<;W(qv3YZiGF=dUeCO$uzp?G<((O4mVa?4v8QY$ zpQ{1pmc|QPKb;ef}3cK}SCSnqMd0*Ar=`+fTn_&n7ii z!y-s5|0v^r1Et*RaULK~e7>PQHW#=Ms4S|Re$4~vQ8K@$#1hbV{T|?c6q9*Xos$zf zpxok82fiT?v^5=w{?P265?-w2{COwShjJj5HTkXdB%ERqIk%j*G$DmP;i&CPS8004 z5WO_4S!uVwpNsC7&({(hYVM*KrE**BQ_LsrST9{d8E0dn1a!!!u*vQ6<)gx`TmGU9 zqvGl=1a+ohIN44-|6HKh7oB1EQQmcv!J{UlS`AN=w=UYaQae9D!Hsg(mNIU>8(VfP zsv&m5X(gC*qN3rZY<(X$>9mrc_hYWnW{EGcSJnBKOJxrE@>}zom>oNU9Rz;C;Z8y0 zyK4Y$Yiw(WXMSTXm9+0siQe0aj*A-|sdHH?e^$xPC?ntL_|oJTp;lLFO7=|aWwjVw zMkIi*XD`%LB+6362s)WUQVxZ`GBNB+54iBo<*7CP8n{$0xTb2wb_$Urry5{N`Z+^* zZ2GlM?UrY*796TC0H_yarpQ2z=T^=GcZJ>?9=4tYh&4Wg3RE~3o`n-2-`qgA&ib+b zwv*}t_p86#Hr_0)S!QT?bSNz3rODlaJ@F^Lj^94d+Ojsuj|JLmWpXSbr!_RH7dQ=4Gn-X1O02?McnusT03mPYmrcJm+{_B?HT)$D)G6ot(fDS`fuh0Ee*HVC7ebtz}3xArfSlM8h!wpjJ_bFSIiapJL4nBmSzM0=WJtg-G;;G-Gf5@I{=2x;!Zc2X!iKVh16gU{0Z3g?XNrt$d_;B)5Gi2mgd zv+`yEC^LWvObS{5bzQZ;vGTejcCp-hP|)(cy>-nwzME(HlKaU6s^zKgUGK`bP_-B< z{SQDRkRlrLW=Rl(ZC$R3+7Mfmy=-WHK$mLz7k*2|$^jBev~M1`T6n|x;&8l;q*k8C z%ctN_`M%r9SB9mrtr6?xGkydaPCqUN$Ot1cW7o_g-`a+SVvFBqtO}r#!sb`k-@YI6 z^i-Pi2B}%k-)FFnJGS!Bauy9s+Lo8pa*q-MpWEwOuv=pLnn;G2a?}B|jg9YccFb|8 zj7{EGh7K3EL-jAMGoK}WD@n*Z)ZXkD(ZJFYh*veOeE96CldV$A^0V)f;kkM6swuzY zrAp1|Gj0p*9Z(7v1oS_CyP*1tMd8keDW&IQ_J*%}%au1imC|z>+*E8{ zcgD^^xZ~pmPyK|+N=J1f@S zvp}V&Y2&W@pnQ3ye0y^DT|=vw??HGtFm%*TZvBq2U)F{1D+wCCcv~e>N}lRhvw}To zJ;ZZ|%pzvk)*5au&(Qo#oH5=Ci1PS4BPU3JJV2`bYin#BYlNcKR}U!r5$|qxi)J`- z+VR!}sS!soV>R{Aueww(16g-t6eAtOBdbc35<`u>@vS@94CAJP-* z9{eZoz}ZJKu`O4lXX(;It8c5eUeEIja~Y;7etcPi&j?8(ajRPLC_V{}GcPkS!z&-t zb9i8Eo1SglE!-jiG0{TFjZ=%;jLg;qSr^k?4#tSAhpc}}B+<19zMDIiEd#CE##^9$ zVAjS`H4V|#?C4z%AYe!Li#XwCn=|PZNepK}wl|>Q>A``1u}zzHEQII$Tk7(>AmUSX z!5_u){fQe?5r7;pI2pfn3EnXSy}V_?8fl(#Z=ixJbR>AvpLWhGx6euf=XE z;J_ghsIn*#7b4km#h--DUT=mPGMZInsW0lQj2Bfr!J;=jH2je8>U3qT@Pv`e_kM-=xdF1Ja5o#P}(Qm5)<{hJx(p&jnyUP5>$tS--SHcZF4z zy8EZn9ZQJ3Y9`gl4VSR6g!hZJs_O7&emwA+?MdF5oJLB&g(2g)Q8m|ImWNsT+(fur zTdAmZrS3NvK@e(W#ufB{QpWH3Sy%8K40~Tz8?5=NP<3GPZMcb)ky(4~DD$#vo&#a* zo9fwhzw1P|`Nt%0I8g8PT!ZhBt^g!676$5ajmObvea;5*Q#mn3d`FmHkw2`)$k`E+ z2<2`{?X7v&Zr@lGxq@Fv>joxJ7($K;JVj!q;nrT5}$MxR`?cAa- zKZ4nF>HB6zz)?f)=RZ}#HvIdJf3HALi8RLU>nW3}>tXlQZ;6Cuh)SA1SkUfv>3sZ! z^>T`9tinKB64fp~34t)cU?A*P$5l}=RzLJUDjYwUc+16H{ZiVEJnxssV-lFU)oR># z>j5g_*YVrNUvULYmmL57%zO82>7A|%^I&)J-@)xy_mIo#^|G?!SM9$lmAN>)vMN3I zTzfLc!xwAQrH=l=IV~q&U$~-r=L*_)p)@b^(wrD0n|+KDDVi&2wz-m665+x z3hS`+g=~NPGZ-;-K>6|bj@HCH99y*Gk0)2X4YG88<3wGaQu{k#VYz1DD-#4Gwcba& zJ^aCK;ET1hpgN#w80hj_U};0v=G%S!aN#ZN)*PYBH!@52i$?i7X(Yt0`Q4t^3mC#; zgxY1Dak&rNnCHpa2H4-C!3(1EuXyo4kG~v2t`7={ZF8WEqqY7ex(;Y6r6)Kx#haPa zzdn)k3LAfxP3jlb0uIKc1L!?esZ_G)ZIP4*36lnVZHG?nKdnExR!m27BXnAE7F7!M z&}xu&yhNJYy5n&2;cEX8c*|a<7ew?_vAi~mDXw`X~DK&a$v5nZP6G867I<&JEtw!))_s>G~#jQ z!@qcK$6rGrPIy`}4WRLFVHbAh-P@Xq>!HCnD;S6?!+!)8(-#C3Q*R5|54$t>3 zWTFC93B820-VlSUOLZ~M=d;&YAD){zU)1&}2feP4L%x$!j-xu-k~{N6N5q2Byr?mxoB7TKl7mpUE@?;VC$)6VlODWbHjP( z$$gHT7y$uj$In*~vFKjdJkK8z>BcL9XY@Im-o2cLwm%e?9J*0cHCdV83^KTC%elB? zutuX<;1+0Nze^hblIIYh=nmeL8qFOc1s)f`H`d3-geMxI>WPuw7`$>R3j0E= zRtz-q9U+1=o!z3t1zC5HGFvtCYtV_a)1}$JCM*2 zvzz$-jn>C^+1`|X67=OCt7oE;`hydp&mCprw&Y+`xzB5sh8Pbb)uQOXiT?K5_pD03K6;*_f$}Gc52DqPGU^rW zDR}5qk&p_PGsD2}zpxdMvTifZMn-6t^eR(mE#kW6ZMW;FM@OH@6n+JqJq%Hid$$2Xe~#x?bSKZ1uCG3)IHyw$a(`0yNLe&k zuO6Ug*x%Glny6#Q{MEqC3Hu(icAaoI8^#r0u2S=e2^0;sG%|4aZ24VxlT=Nwh98cN z9${aM6VF=ttJk`$dWqiTX$$V3>345Z|F&^3e6ZskSXYbbpt67!?TGKlwB?_qFufbP z_^Fc$QmzocWs?wa+wFz-1y2|~)2(I$cAAq6lE87^Nfz-d*zWx^zY;ikA^dqq2BFQe z@5M_)zhyV7-pG;iYBWA4Z?Nc-cGJ{fBl7r*cqbA@Uj zt?*ADmzOkWFvVHf*Y6`4UP)Q8^`lEm_x3rYK(6AdV9{*ct zMjZ2B_P9KV6q{AS8-Ez{uZNIq0~GGQvQa`glIKJ%zOr%omidDDHf;mLgxIdI+%I{eCC<#6J7^agKleF6MKH+K-Hp+RMJvw{4$92<%5UXfaqJa>oLPt02T3e zDEvy}EDcwvkI!{?g%v`uGXe6~x!+ujv8T{;!SypaJR4_=?G_v=ZWmCs)DZ!icG*^n z7f1&h)g?aU)OIvzNgSC#l6{@tFN5#?_Pt!RsC@tM(KvuPLw+|=YLFPN`(lAV8zioZ>0J+3{r8D~;5tVdhCLJY% zQ+y0B`B%L(dobaUzeR~qOYCLgD-D1#qYJQ#*Wg#wFDLQsKZ%KYi<-KB()8?0F}GPf zY+0lRTAKWDg-&s4a~^?+NOyq3ZB|f8zUVpduKU_|4;0YC6#<(LnE2R`*o_W0WQ3C! zc^-(=X_zE#Sb7@c!+yNJ{i)Ze2U8=L;iEYY9eJ^6JFnh zThPEx)SFy-X#t3FDaC_8VQ|y_G6xATo4mXCm=ROppHi?rCAAe@_|JEDiwJT?;&ftr z)OIb};0r8`5crh;FL#R;3CVdsjl~Vh5QO6|1n2dVGt}yS4e+Z8=x)nvlwNeCu2*8< zR{pANvPcwK`S@dT+&0JV1)b7p1QRwPAIB7tZ;*{+bLy3R0+7|MEkEgg1s1&fYF{GvCd{){s5uwG#dme&gKKA!f~${Dp%F$?ex+NlN*56@jxrdZ`$ zvgs>Br2W}?yLEc`pL(8Wy>e9^slqs%C@*?G`u14Tze|anA@OY==u(3QMJ$U?otIgvGYtg%j501gaQ;`6Kze5Otyy}xPtn1dT%qdR6t>_5 z&8=?+iujLWySiGh$4*pRuCjvY7GdT)8rQCE!EyT7=X^Qks7JzOr?lnTZ@;rZOw#_- zH8g#)Ki>Yn%WOG=eTGTjO9lp{&!B>hAOT>V>8RpXu7|?+>Eql}GSFSZXZ-B8ow8K;7v5!B+Dh!!|12@SBr>)w zebGA$B~vq~A|<0$ehs*=`zjPhU%sdgO^-fD!1}|k{DvV=A@I2$g_lL|zE@psgnhv@ z@ib{L3r%5xcV{>^YLK}8tH%BHd7G#!I_#;nxKV>Y30ozxv(WLK0#W_L0C_`xLn-6& zZ66Gnp(mB^x4#WIfhIov2v2$Fvq>MG{`#T!xuHpL0xzx1vA)Lj5cld<;sfhB-NdIJ zhtqX=3iPYr?h>$`Cxtt=e;ODRZ8tS5a_QX?K1I%vAB&=b843VM5w5<~MOC>m%h~8qBa+w)&IlkWvv%}E*=i%3jZki+D=u&mg$%Z)r)l!e4Mc|9s|+Ezv3jUe&~ahLW8@}iu+%w=m83MWgEFbu zoT`$$!u*<8_lsQzh#9rJ`L_uZ{6DgJ@jHM&&wm!}(RcdlJSTCEdp-}v{8V3E@N_Yl z_p^RWxmuzCk^5m@-?|#EnEIotH=hVTcwe@sf3n21hDt?NRs-2{2x|P`DW(vXYvId; z$e@mw03R4!Nn)Pb3?%9V4AOTHp8J;&0$DZf|K$~#a4t$AFhKoq-6@U9tC4*pWc(L% zk8qx)eF-$t-t5cPLUprYJKwEQGTAKZR{%#UL3IjSNT2`!zy|22{RVPm4c<|n6@9fH z`YXBSS}l})RevP+=E-Ne>rtMr!Di#mHkYo8VVE1YU{>&H0m#I%m$rO*&TIu_jI~t8hq{# z{1h_zcS2&Jr<{Z5qi9)O@ZxvZRBYebCbx~pO5FL*$JEp&#)IXIi-BzZomQb)i!L`R4e!Ru0M?wfz)T0V#6PW?b(V@Ith5Q$}hK= zPdLoX=ak#;nriv|9d7^duwJQpd5Q1k*Qi(~8DQ`fJ1tJ@8SGzH#?(g8GP)6*r;EqV z*k_GUu$i`v{K|y&Fw8oDs`(k<$m(aGRrwEL%%T}UmgR(O9{lxn^7i2^Qu61kpXat2 zG;G9l7l(d;$)5Y<@tNJdkggDr=W4wDANst%u*F`3+1j~D>fF7(|D=CNo$mv`vK~3(X{>Gg5nG;_RyQa#-j+wHQd}1jj$DO()v{!5EVO;5TKTKR>wf(w$ zj(45`w}cGQSgNM4(=e`GU;H9TL5dl?HRV}qKdamFem}z~UiH($=g-$RY=0Pu`oZS!g`pX0)7la=lA$_GZx7Ktd(s z^Mr~re7P?B<=ind@tGuVK0pA>KP-#DJWUFs0_hubifD=b!5cHsPL-|(SP93x4tX}| zzUPasq|r4fTGPGKbSChIa*ipK}7;JDYL|mFOveJ?=gstAVFn9q`>+G zBf>cMIl{DUWO93gX!l_yZeWAa5u)rUlc)Mq8I;m*gML37Xx+a_f40T$)XB=4rhVBi zp$_^$W#+jfwu!xKJGy0#?|SCb8jQ(s-gH+X4tRh!hw4zw&g{Hc*madV!+K8KbN_?c zgWhH!Z2aVJf~k4QT)k9k`YO^9vNr1Bdc3~$M|OxRDSiN;LUO;oG-u5WuV%h*ChD_z z^oQ1b4Y=}Xee_Q)DBvaGhr<{>N_G7iM?auYo6nB>Uny1FA(+?j^qU{8l;C(BYRW$$ zZwkxw!X?G=`V1I^OMkBl6#`RjIn^KeY?bJC)D$E(dNjb-?YdzPkco$?l5NqZbj9z> zlEEXK2MH_)fv?XL-JWWET6C&J0f-`CiZ49=)ehZ zZDi{YC`V9fvp$*L1}rrv;Pr3yOE2mv^#Z)VgH^z#XlUXnxS?>HmV^C<5x5Uz@lj_h z<7S_mU8hly{V&|dVUKaRremgnDi-P5N)vtREzH2!0YfC^T%PE%{@p2ns+oh!u@|~X ztSCm&!mk;t=bo^z%*2lK&}d@dJ zckU0c-wmtbl7)0Vl2pk>rYBP}x1I3@XZ3s23KYjKS4+Y^8 zdu>_XapRK%g|-LZ(&viVtj_DKe-JzhOGDG1f~l&Ne$kkEQTm!pfJxk=ekowTi_)Qcoy6+I}Un|DV+f4`Y6ZMka#07=1*U zNNv**3Ej?HdZ^6QqMbwmR)OoLGY-m%%d2e-@mi}DMz{S)kXwhN4Ng=b?os_0^l+2z zkIx~+=PnNgU!aM3=|kJZ_OYtB9`tB%WBc^Zlc$u3eIE`FJn^7?iqoKAdw9jJe~rD} zJL3Jo)!V&YrF8I?ih(*)mNf|k^8lV7n=U*9DTBi=@J&~MbE>-n8Dmcali*RPDY7OE z&5bf9kIn!4My^{=qKSI6#QL z>-Jq5_YOeil;(gkF~NGNnRpd3%;YwLe*f~xl3OrbDyN$UWt;;z<2~YK7vT{@YeQXn zdK`cdHS9IM-3_9GploZu%U)F?RVAIpu{(Cb&)&VO$8{&nON$zgw&Z&O| zbOfj=eQy&A_ytw@6;P?4igZTF5Gkgy{V6v^8NB=csU54}l#uSg@(WLwLa7rn) za~lq35|))PeI|;k{Y($jcx=-V1rHE|e8m*3ybeEr>gM?06Lj>MA%`cG54AQ9^M3l4 z*HhIB5N$z|{po9s%}A?@KJJEoxi4awdK`Jgo=-{zl0N@tTM4~dft-g6jEiKUx0`TJb*q;wZzof6TMx+%9)gIc@*3&bvK2 zm9Wh~H_F$F$3Etn|Fg40%a=@G>k#`9t))uPAkw{}f|ZEuxs zxJ8kE6z!fr_;7Q>XQUGzr>Rfe|{K(er+h zW@*_Q-`~N$ko{^5+4`3UWds!5!yio z4!Iqx-ia8&L8j^g5-W@N#{DCUUkJyk*8w7uxV%%e&y{&S#~COn19+QYe*jNZuOsGg z{>UWx&+yt-bY1tlN9I!j(>M0Z$rjq>^V9A%ZgHfII*kvzr7we~_XCFb`q>Ay)xqGJ zIk0$j1k^W5GcQ=axLpxF>y8yK?=_gW5&E9%h6_`Dm0a(R4S1Nsy@BVXJ&0evClhEx zZ`ufzBwz>j8+aHUUJn*{UU0buNZU@yF*6vj+7lDO6%v8_!E|Cb&Aq1gW%k$S{C@U97l5#lEP0glzSW_jT&#oS)FvMW5_<#E$pA-tI#(EL|5uS03! zvK|VCRS&LK)8kO%)f`vV<p?hA`X6wGA4uwot0@bL_Sgi zv+L_{VjAt6>L!h9uV2k&%b36HVSsUS9mImGMH``D`mGFj`zhI1%pu0Rn!eEg;}qDr zT}$Sh#X|UQvXVK}Kvm_(F1iln-h+_$#6Z9BI7gtzBK-n;zG77RF4LpK7bWZ@+#Cp%bS1tVz3# zewzZBe+3s&_kd>jZxBc8feDa8cfif*S7#xcGLn9_wD6E?)4#&JUk~Pu5Q>xEe*c^PHAqB)oiV7aLNs$K8}rDV_mfix-14WboQim{d4ugQXmbUUC*kwcgtaz<$k>wke8HxdQ#vJFoJJ`{wyUjpt8RF-{Tp4Ke+>lfeM!1oe38Cm;1(ai?9|2?T3Q_wFP}NrO zP5ARyya5)#dtO?9SUu{K^&|p3y4(jHecIyWd*=CsDF83P!aI3)02tb>NJ$3dGc*~~ zFsamMZ!gUY0WEOhwke%)ZScM*a&yo-FzFlkNpo#1z*FWBAE@6p_Vl`xk>yW!i3SHO zJ02Vw4o2-8p=Y?frK8|&sZ{*x(UbCGH%AGhm$dLdiw5ZH7LBK& zLyoPf-htZ3ZzeHJvz);j-TgQ=X17bT5L}_Y6!SZYlu`TcSs$Qc{+ zq6uVxh1a6SDA!5w(d0FHv3!x_J?5(bSS+~R=R3cfD${XI(3$O+<%|F8`|eF+ALI2x zRE7Nl;(_5eA`iTO>DNLj9I$hjVlx%NXMA-E+dGxwvY9hCi_Ok@?KXq;nxWZ}4fyJp z5&jY8G$L7I^9?}?=gmaPbgtZpRdU1@XLW7ZnSV%VhDv(fES9(_yHnVI74%|#GP)Z! zx{lh2m2)%H{?~J6Av@WM2Uf_bvC;+T>+H?kIDX^a-4eWXkOckJ0VN^ysI2X72Fd^A zZHL)o`o4?T_a`2;rc`$sD{0E*w|7mpVLN{o2n=)ZXF_V?Dcd$&olEy1Wn!xl zq3ZKR02MCwN*zPx`rh;{+V2z3&*<_Ff&1W|u?RQ%qQ}qHLWO0Ni#n+tdsU))z>Ag~ z2plv0A|-q$^!+Wje~UHJqPA3zjh--{l53V7Vc)@Gw%Ms`&u{%3IX@w{)F#XywB&a> zsrBOX`lRd*!+>*)bMFyk{Xl!0gMbf_SesDZt51#E7B_-w=q+)pags8zY=W7 z5&O<}ZjcXFi1a3}f%ZP;$H;8lo93|=^!fs8Mddep4$OJ`V%xu;s8#t}9)j?keUxwI zzqZMt^nU4IN|RhWeE4lxw(#BJ4^>@p9WA(l|5aY`&Ignh^&cKJcI~ZNaq+su!W!A^ zzlFo4Dhp<46MLTmPN}NpPrqEANMHbY`M`Q*qifVHf^J8yt*+T!K~VgK&-w@WQ9-nn zsu*uIm8#`;gIdSEJB9CMZUEkG{$miD>-%VE>cUemvGv%RfKAEr0IGs_D6D2M#n|_W zSBz9GA4wqutkO>NW;7^@^yx_@wFzb&#mO5&}1ptf;EDIXb(n8 z8YcRtOE}8mU3#?JV?O!j*90t=BPU}7t!UjAzD~DU{JZ7)qBGzY{UA_mr`dE9-0&;wwKWPZ+mZgznDZp&xT``iJp6`1M+47X7;k4^7)-!BVVe1w$IKng4>Y3io~ku6GQla=A6ql{_coGG%$`@j{) zj99E(0RP{n#dAaw@LGbC<*@ix^wT`5Ou<@cBHCE{iMP}@VUw;;OUcX#_l^6CxL{Q& z2C9YwT{th}yL zzJjoiQyfN}GnmM(azbWdvFJ8`(=?l#_?+%O$}9SDqhbbc@0cAaj^@h8PR5;yA1Ui2 zrdBH0Kh2)ao`xeY4gM7nh5kJ5Jo-_)r7;_q^|NrfQ0S@6iL8Gnu}SV4AMsPaG?zB+ zs(oqImQ_`q%IWKQK>K#|OcTb~%P9B_0C?uwIuG{);>hJ&*M0Or444W9j8b`Yf7xGP z>Mi6wwj>@{J{7rNeb@aIiC4W6cJ1~n^Td}Q!R)HEL{6&Fko)K%-f8?}>RDDMZ+?x40}MGTCA|C4R}zfzI$TUOZ?t>dKT_ADF&yj^RYT zpgq>tt}0tvq-RxiZ$TM2?9t=N16AFQW_+)j{h3|qxUT0=F>UUCX@iE->i0ErRy11UZVNHS zy{3f{^B&%Rd{=}~O*`A-&ivdk!Vs+K%joTSnp=36G?efUrPvCWM>CO)uw1|wpP^aQ zcYOYXM|$9Bod;zs&e*e0-x2L>(6>}dV<-g~v>ocwmmV}{XG}U#k51ni@h1O4mD9w2 z^r_dEf;)Ud7l`T4OTy{-s%@=P=fz_rmhsEM2<4vF#EMzYfenyTGDWt(6p%B_Ip+Y` z1n13QQV8Dyw-Tuth+bxC7@5LpS>+w6k|<)z5qeIJG7i6v?GhvRMt<7y>DNFL-j+sS zZZ<(dw>6fgGqr*W{;in}WJ>L1K-VcuzU1t{{}g9*j~ItLluTPR0)v>(y=np&ca5nq zyyqxvs3OT*?+ImX(}78gyBZ2F;;nzL>!I*%qYip-i_g+`@0=%)|$wQ$sA?osalXq`1^=pq!uXGH%-~L8BE@(G#X>`=(y#beE}&Rj!}FRNF5qnD1Qttiy{5W7Cp z2b7xK%?>isvpk)twPJS=5rttdQOsBA&34qiO&Xxq;B}?$CX#uQznOi`P}I;V7A*-J zERq}DFyok5d78L#gb?xYpG~DzZXIiB1e1)Yz)vEfBTyfXzl-23^O~Kr)-7{Qj@cu# z`(gF1xZzc4x0A@yUIbIk_;w0=pNrS{;P=N8j=Q9w4i4ruT#BE}NkGLxk?-!ggfhebt`a3_PVsZM*2WKWOqv+>N{x6>GeiD3+ zrRA$8?=2KH+~2SFfTgh_?S{*B*G(OL)#&zAuqTy&db__){%2gbNx6?e7kGSL~Q+9Pl60qHuRY(Ajr z!IvMD(g9Rt%}heqPFhbFI6)%t1@1E(jjh79e?`iOXZGy`8hHm-fB z&;BUw(xP*%IthW?EOLHLuh}Z?d-KBz{(R}QqoG>I#);j3>o&G`iXrFi=)racm>2x> z(k6kYAnFm>5Y|e)*j?-pWqikKho(|Ikxho#77ovsU=l<^5;Y-k0KDa5_!Rte8e0?& zD+(z|nZZiBE1Zu7BTo0>liqrztH_!JvAsE6#T`KHMV_euJT`Y%(>0L};0#cH@nZ9)@iBOv*fK)2no$&SsqQteQ*W3Zie**ly8%oks zOqDe7eN($+(aw1toP&3r2=VI-jiRLl_q-Hh^Fz7IuzeV;LT%h2&p+Q5u-mZbxvDz& z5FA3zcjrHYZNd@x!b@aCpkdRaoC^qx=n@}f{=x)u77~AI;InuEJ{SFv5d3^kgX^@q z5wq-AbAO#>uZm)4s?#f*&ZsgmsFAaImSzP7-pWj_!e5nN4@XUb=iU_dZ`Z_rz*|^b zR+@tsSc&KQ&?5z;S4uvYJAzL4=<@8otohjAeX+_+l%^PF(i9T~l)(-)wWuDBRP+<)+d$N{=8FWs!L@4{?(@s^+Or zX`JXB5JvgVpVUq@0hVn9Ghf$9<*-)4zj8o%@BuA0&wb7NQaL1!^zjbcZ#hpU511@~ zYn|cLF4AWL_D-rtDitBxRn|aJ7v)PfycUitC5>%HCm&GOo&dxJ8)N>xoxwKgv=d>r zjh8>g*R30tf&vS6?^Go#F}j##Jbe!KJK~?TtLUj}KF`3qoCxT+IVC;aLq5&D87Rvs z3RE=@Uw%rDzRl?HAw61?$zXc= zKDou#4CCF*2pXy@Szu$@Qvc#gQF^xv7|68mW?odb#4yURV5o5r=tlyD)#S)N*;?p$ zT6pmb57USWs|t5)v2%Zr-Wg85UPWB}wv6Z{jVt%>2H1Vg!JM@!nQz8KgIxf`j@95EMF3Bg`1&8?V2SH zgVf*2(ajnU0CKcqD5j8T{!7H6n4N*a@OdS@iweH1V9kM?lmcf zWuaQA6<)C&u2#%q#Cz{QAUcmuHo$pToS3Uf)U zh~ZmQ>3et0eD}Dm!`9Cs1PH;vl-|gulti^}7et`=2tyqG@IlH9VA^CqX9>(u&xQ+_ zo;zp1E#5iuxEW=PE98;jnZ}MMKDq|ao{0oNQ&GZ~0zVnt#F@Z1Ihq!!HcO+9RI@9= z!luF`-D6!HAexeX>J42qGyTd$-8!flCRLnI7t}fQpL!_J%{agiam#(7#cAE)BNx6l zkd1ZLcrrUN`?=Dnm--BLFC0AG3*?MRy-4#zXoQ9856X^yN2>P(9I{Lk{4*-DgY)B+ zd5)lA^sB^Er>zViVq^25da$zhZDmhkh(6j<`;qS?<{iD^s42-g;+-Z8yWvSM+kxfs-HsfOIC!A` zw;3vpZ{hSoZ;sD*D*dkF=DlibqGuLooag#eNVpXz2cjGYc<$GaZXRDc+AMQ(Ild&$ zG^*LyuUT1;+COG)>v}iyInyvH{8^&(Zl9-%S@idlW3~tdVum97J&N2$HHQzkXrHEi)7tqI$*YpGqq-i#`nzUZP36Q@*uLn_{$Hw4F?KRXQ&3it(ON zYrF1XdLbGA`5sK__jYzuu_!wi(~Q+?6Ok;$K0CNT2(6DT6nt8ycG3vzec+sbU! z{%{i@>0Z@!{o90|`Yl^2w!G|k33T5}4Y7wCVkvW#vEg(dRWA&8{tAf?1`+pMKAvXS zt#3T^U02o9c)Pn&*0gBjFT;N(_Qu2?xkExvuFdhueQZnSyvn9)$;L9xdH>A0tJ9%v zK?wHRre#Lo)(_N^7oS*JNqI-FhI`|ig`xitqF=3z&2p}VMLX4-1r|RNDj%)Mby(O0c5!VHmEnVt{f0LQ zD^9Z|CsmmBTmoSk{5Dhj%aVM=kCConQ;(+ac1S8?Q2pvdUUS|`-2d}p7G;Gsr;=8~uDM6;yAlC6(o7q?SB;i_gvsJH zC9A=EbT}*`92Al|S-;^qrvtXLop->Vo2h6g{|ESkjzgG)2x!{~e%41iG-{JBHbK>W z_~Q41o_beZhG$={j5|FMM!cViWcn3QA@Nn}9ZYo8f*k&Og$cBq+@4ucyNiLd+d|pA zecCs3@s20vydXV4wP5{X;Xdx^*9FuRQ5t2u8LpEWPP%p~$Kcu3v;4JNj|*iypUt)z zo+d$enn5ZBdV&u#*mQ^1&&SbR2?Em0amHUHkjD)7(iyG<^iLdV`_+5!#!C*^HS@FVn3w$D`Ua*CJn9A z_n-)ly}75Os#g4uJ{S;j>?@!25u(4MO?x|uA~__RY~Qwh>hFenIVHcEN!ISJ#{(TH zQWKt+#rw%765soJxYKOIhGqVNCmbU@dXH*XDDH8Ny{T2upAG&wuvUuJw>6$Bt?#+x zmJ%|Xd*s?jpYF-{aNQBIEIR6QuAJp&*V>_D(*F_l=Fw2Uf875}qb4mwM9DBBB$X|U zZ752FDH5`l5VG(4q_VGN-$t@#U$Sr6*BMJ8`#yHYKGysCe1G?Set-4HoYOfR@Aq7< z*Y$ip9t9vyU@app)@FhhG8Eh%{u``)()5J0^>JMMn^A`!wR{^vl_#ck|AaZ6Mvd5a za_UP(f90Qc*74#u7_br9jf-<|d[gk*)XK*JGw!Jg7bIA)qf##}M+GmCouYgcQ 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 literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/3.result.extract.cr.00011100.png b/lab6-steganography/results/00000000/3.result.extract.cr.00011100.png new file mode 100644 index 0000000000000000000000000000000000000000..fb4d8f4032d12f08111bd9633e01a2cbb4143fb9 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7Fu1Wy;okcv5Pr(fi1P~dSr-}~?X z^y}Vi&MR{cDs59&|E%G+KKM=Ap$Uq8at(*S%Sjw^Slw+t=XSLHL8G488&Yj9vnW{H zTf}fQe8KAlpH;W`e)+lY{qf5Y4g3t(rd?S6{2_a}qCNM|hD*)$42Rx3Wv9G!WQ@CT zq@XutDLZQe|BJ>)PwRHro%mPq7Z$b AApigX literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/3.result.extract.cr.00111100.png b/lab6-steganography/results/00000000/3.result.extract.cr.00111100.png new file mode 100644 index 0000000000000000000000000000000000000000..31bbb88c64c16fbc5e242201bcbe4750f8f4d989 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7E@o2QFoNX4AD*9^HB3^<%GUif|g zre3T!duzl`{utNx1($s1ywbORdW!EsegoS-kJHXYogbD9GN?%wMl~?~)435ZQ_t)$ Y$xPmii*=z>O)1D^Pgg&ebxsLQ0O&+0PXGV_ literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/3.result.extract.cr.01010101.png b/lab6-steganography/results/00000000/3.result.extract.cr.01010101.png new file mode 100644 index 0000000000000000000000000000000000000000..70d7e08f0b72e30ae4001b0014f607b3ff404127 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7EDxTlL_NX4AD*9^H1C=A))7y|-)r{X5Kc|JW5yuKv4k?fHI& zgyXU)pT5eS>t|rFXV}2mAkQ%212co~4@L$~dxi@ojH|kpODwx2l|j~ey85}Sb4q9e E0MvjtqW}N^ literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/00000000/3.result.extract.y.png b/lab6-steganography/results/00000000/3.result.extract.y.png new file mode 100644 index 0000000000000000000000000000000000000000..5f748527cd13366b9ee82c4570015e64365b3017 GIT binary patch literal 365 zcmV-z0h0cSP)F0|Np%A!AwO_K${+#Y*BHqJ)vQ{E$^#X^D&X@=7}L zD}CoMi^L{rzVFc%;k>5Uigv3OCTQI{2|F(p;ik(drnckQ?`2|JBjm2jLPZ$0X~ ztnCAaqsPFo(zwUaiTeygiZHeqigvzXh%JWCaoH88na(oI(KSPHY*dS%AuH{DhFoL{ zG3-pRgBjL1a9aUWhqo9;oo_SkFqD3oew?!mHP`J7S5tZAytp*LuuPO7!`W0eI4`>W zhM_W*73T+FERfz~$mejBVc(UNd#xTP{eakMDi^2@GseHhBYo-f?czUVP>JWfG{OO?1Pd{{N00000 LNkvXXu0mjf5%8z@ literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/1.result.embed.y.png b/lab6-steganography/results/01010101/1.result.embed.y.png new file mode 100644 index 0000000000000000000000000000000000000000..927455b167db20560d9f314aaa3c655083aea5af GIT binary patch literal 68454 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⁢|fWd^IZAM;7Se+LgpzmBh?3$6j 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 literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/1.result.extract.cb.png b/lab6-steganography/results/01010101/1.result.extract.cb.png new file mode 100644 index 0000000000000000000000000000000000000000..ac0307eecc413a0d95ac79f292b936c88e434aef GIT binary patch literal 329 zcmV-P0k-~$P)OFxe%U>jVEYE#Ggu0rNHw`u+Fo2$sm6hZYG@h|0mc?z*XP|c3;9(AV+@BKN2t%a2KEn<^?4K zyg>E71$cq$4aY|oT(2tlUP%ah1tIALeG1vz7cj|B2zh=|Nb_?-(Mt(s?>dD_sNcRH z<0Su&gzeh+K(I#yq(X4{b*He81t)|b{u@G2C<$TVgF;%!oq{Ha<3Gv&m{9aGLUa8D zf_Q;>LCjwZ^|%oNb^R1VJMy*AjC?AH7nm=)=l@V(#;p{nfsKofWgNF>uoMo|4(~|uF{|;#0hkrv|Y+5yn3jXW@a!mzyLcwc#qES=LpRN&iQ_sKPETe z-HZs4U9K<*xL3dmVH)u9LVrzU$O%{|^v59!yiA^eb~GrHAPg491)=&|g#MQ#1R+D; z<0Zo7ZP0~i2J8}O7ZibaK@bLAhzs-L`hrybM+*LX7|QS$0$rF1^Daz;aTiE7COFRx z37>x-lR`a1O<=ne0cD|_VX&(r;BJ9*K@(UPB!QmZz30#mMkT%8K;xg3R}H^>bP0l+XkK*3l}I literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/2.result.embed.cb.png b/lab6-steganography/results/01010101/2.result.embed.cb.png new file mode 100644 index 0000000000000000000000000000000000000000..cdbf709ff190ade6fdf0327916b21b845e2846de GIT binary patch literal 69855 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

    k<6Vi{B%h$q|S!2copE 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 literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/2.result.extract.cr.png b/lab6-steganography/results/01010101/2.result.extract.cr.png new file mode 100644 index 0000000000000000000000000000000000000000..a4d310e28894187edf4e035e9d8fe7fbc0b99b70 GIT binary patch literal 242 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 literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/3.result.extract.cb.png b/lab6-steganography/results/01010101/3.result.extract.cb.png new file mode 100644 index 0000000000000000000000000000000000000000..14f24ebc92b629437e8d09c2602cfd6649ead63d GIT binary patch literal 339 zcmV-Z0j&OsP)P${|0kq7_){ER$4^E-8Z>W?7`K;Q-OYM1x^jbd6T zU<1WYmOto2Iu1yJQZ9-VoGJFcF-8)doAL*rae!0m`{+M9Yh6J;= zpMoXWyN}0M$$yhD9QB5PM+7bfrD45O7~3Kys6YHKgyr8ZD5wh`6r9V$JB6H(Z2wCB z#{{D`A~@HNA|x-cSxDx$1-sn>Lg@N21h?gF!D;!Wki5X=Mc4eBLZsbHA=I$?qSlRe l8I>t@5tRI?3~K(2@CFHB)Mx62ZI=K5002ovPDHLkV1jism8bv! literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/3.result.extract.cr.png b/lab6-steganography/results/01010101/3.result.extract.cr.png new file mode 100644 index 0000000000000000000000000000000000000000..0edab5aefbbd6b65875e2c96d53f0b704b808a26 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7E@kEe@cNX4ADQ@ptt6gXIqzpH;9 zHHG~JGwa#gD`qnWs!6O|eC$cgjh+T^hK*JK=e%F9@ZgAi%3}U~Y%iD@7x1%uK~N05 X>mMkT%8K;xg3R}H^>bP0l+XkK*3l}I literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/3.result.extract.y.png b/lab6-steganography/results/01010101/3.result.extract.y.png new file mode 100644 index 0000000000000000000000000000000000000000..ea91b29540b1cc8904f2fea16a4f92796570f552 GIT binary patch literal 376 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 literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/4.result.extract.y.png b/lab6-steganography/results/01010101/4.result.extract.y.png new file mode 100644 index 0000000000000000000000000000000000000000..4463395db64bd6c990369aeaf7350dc04d8262be GIT binary patch literal 371 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 X>kZ%J^+d1SIfX4&BmZ`3RTrN`$en#Miq?) z!DuQN%?MO03*P0kL66kgq%&+x$&v+&9Lr@ZRbmQhu}(s?u_pw-rB kNWd!a(U2Ipkod>AD);&`6Sc3qflV|9Pgg&ebxsLQ0GuHfOaK4? literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/6.result.extract.cb.png b/lab6-steganography/results/01010101/6.result.extract.cb.png new file mode 100644 index 0000000000000000000000000000000000000000..84e2b8d595edf1e9e711dde69a5e1aeedb02fdaa GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7E@rKgKyNX4ADS2uDp7zi*OnDMv# zUr&PQk4HJJhtJKKr1>}3fg7Zpp&{4d*8k_Z zMhpyrYzzvg7#Lh685&mn-g(Z_ee2Di%pvWi>=wK!Nm*!Q}2}uplBB8pfl+GMZYT z+5X*U=KqUUt+N`<(-@`DXi+y>1B_OTl(iRLaf`9VENlNC^$^(pVeoYIb6Mw<&;$Sg CCy3nu literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/7.result.extract.cr.png b/lab6-steganography/results/01010101/7.result.extract.cr.png new file mode 100644 index 0000000000000000000000000000000000000000..84e2b8d595edf1e9e711dde69a5e1aeedb02fdaa GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7E@rKgKyNX4ADS2uDp7zi*OnDMv# zUr&PQk4HJJhtJKKr1>}3fg7Zpp&{4d*8k_1$Jd#=k%Rde^$=l_AZx&;J}Y4l%E-k7I9`SN)fP!HkE& zVG1KdhYTgV z3!u9NWLP=FtapDHSDoI)%#iVklLPEVBuhYsSu^;S|6{nCdY6&GDQxl>=(oF&ZqR!2+v*@noW3OnVoJ W3Y$DMWd=5Y7(8A5T-G@yGywp7r;~pG literal 0 HcmV?d00001 diff --git a/lab6-steganography/results/01010101/8.result.extract.y.png b/lab6-steganography/results/01010101/8.result.extract.y.png new file mode 100644 index 0000000000000000000000000000000000000000..84e2b8d595edf1e9e711dde69a5e1aeedb02fdaa GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^4j{|{BpCXc^q7E@rKgKyNX4ADS2uDp7zi*OnDMv# zUr&PQk4HJJhtJKKr1>}3fg7Zpp&{4d*8k_ RgbImage512: + """Вернуть новый RGB с вшитой меткой в выбранный канал.""" + ycbcr = YcbcrImage512.from_rgb(rgb) + comp = ycbcr.get_channel(self.channel) + comp_new = self.embedder.embed_component(comp, label, seq) + ycbcr_new = ycbcr.with_channel(self.channel, comp_new) + return ycbcr_new.to_rgb() + + def extract_from_rgb(self, rgb: RgbImage512, seq: Sequence8) -> Label64: + """Извлечь метку из выбранного канала RGB-изображения.""" + ycbcr = YcbcrImage512.from_rgb(rgb) + comp = ycbcr.get_channel(self.channel) + return self.extractor.extract_label(comp, seq) diff --git a/lab6-steganography/steg/embedder.py b/lab6-steganography/steg/embedder.py new file mode 100644 index 0000000..7f502f0 --- /dev/null +++ b/lab6-steganography/steg/embedder.py @@ -0,0 +1,31 @@ +from __future__ import annotations +from dataclasses import dataclass +import numpy as np + +from entities.block_grid8 import BlockGrid8 +from entities.lsb_row8 import LsbRow8 +from entities.label64 import Label64 +from entities.sequence8 import Sequence8 + + +@dataclass(frozen=True) +class Embedder: + """Встраивание метки в 2D-компоненту Y/Cb/Cr через LSB верхней строки блоков 8×8.""" + + def embed_component(self, component: np.ndarray, label: Label64, seq: Sequence8) -> np.ndarray: + """Вернуть новую компоненту с вшитой меткой.""" + if component.ndim != 2: + raise ValueError("Ожидается 2D-компонента.") + h, w = component.shape + if h % 8 != 0 or w % 8 != 0: + raise ValueError("Размеры компоненты должны быть кратны 8.") + blocks = BlockGrid8.split(component) + bits = label.to_vector() # 4096 + if blocks.shape[0] != bits.size: + raise ValueError("Количество блоков должно равняться 4096.") + out_blocks = blocks.copy() + # Для каждого бита берём 8-битную сигнатуру и встраиваем в верхнюю строку блока + for i in range(bits.size): + pattern = seq.for_bit(int(bits[i])) + out_blocks[i] = LsbRow8.embed(out_blocks[i], pattern) + return BlockGrid8.merge(out_blocks, h, w) diff --git a/lab6-steganography/steg/extractor.py b/lab6-steganography/steg/extractor.py new file mode 100644 index 0000000..1ae97f4 --- /dev/null +++ b/lab6-steganography/steg/extractor.py @@ -0,0 +1,34 @@ +from __future__ import annotations +from dataclasses import dataclass +import numpy as np + +from entities.block_grid8 import BlockGrid8 +from entities.lsb_row8 import LsbRow8 +from entities.label64 import Label64 +from entities.sequence8 import Sequence8 + + +@dataclass(frozen=True) +class Extractor: + """Извлечение метки из 2D-компоненты через LSB верхней строки блоков 8×8.""" + + def extract_label(self, component: np.ndarray, seq: Sequence8) -> Label64: + """Вернуть Label64, восстановленную из компоненты.""" + if component.ndim != 2: + raise ValueError("Ожидается 2D-компонента.") + h, w = component.shape + if h % 8 != 0 or w % 8 != 0: + raise ValueError("Размеры компоненты должны быть кратны 8.") + blocks = BlockGrid8.split(component) + if blocks.shape[0] != 4096: + raise ValueError("Для метки 64x64 требуется 4096 блоков 8x8.") + bits = np.empty(4096, dtype=np.uint8) + s0 = seq.seq0 + s1 = seq.seq1 + # Поблочный выбор по минимальной хэмминговой дистанции + for i, blk in enumerate(blocks): + b = LsbRow8.extract(blk) + d0 = np.count_nonzero(b != s0) + d1 = np.count_nonzero(b != s1) + bits[i] = 0 if d0 <= d1 else 1 + return Label64.from_vector(bits) diff --git a/utils/to_1ch_white_bg.py b/utils/to_1ch_white_bg.py new file mode 100644 index 0000000..5ce93f7 --- /dev/null +++ b/utils/to_1ch_white_bg.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +# to_1ch_white_bg.py +from PIL import Image +import sys +from pathlib import Path + + +def to_1ch_white_bg(in_path: str, out_path: str | None = None) -> str: + im = Image.open(in_path) + + # Если есть альфа — композитим на белый + if im.mode in ("RGBA", "LA") or ("transparency" in im.info): + im = im.convert("RGBA") + white = Image.new("RGBA", im.size, (255, 255, 255, 255)) + im = Image.alpha_composite(white, im).convert("RGB") + else: + im = im.convert("RGB") + + gray = im.convert("L") # 1 канал + if out_path is None: + p = Path(in_path) + out_path = str(p.with_name(f"{p.stem}_1ch.png")) + gray.save(out_path, format="PNG", optimize=True) + return out_path + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print( + "Использование: python to_1ch_white_bg.py input.png [output.png]") + sys.exit(1) + print(to_1ch_white_bg(sys.argv[1], + sys.argv[2] if len(sys.argv) > 2 else None))