Прописал код для core/utils.py

Добавлены вспомогательные функции для стеганографии LSB и DCT
This commit is contained in:
Игорь
2026-03-24 21:36:21 +03:00
parent c8cd88e1bf
commit 56ff6d2492

View File

@@ -0,0 +1,128 @@
"""
Вспомогательные функции для стеганографии
Модуль содержит утилиты для работы с текстом, битами и метриками качества
"""
import numpy as np
from math import log10, sqrt
def text_to_bits(text: str) -> str:
"""
Преобразует текст в строку битов.
Аргументы:
text (str): Входной текст (например, "Привет")
Возвращает:
str: Строка из '0' и '1' (например, "11010001...")
Пример:
>>> text_to_bits("A")
'01000001'
"""
# Кодируем текст в байты (UTF-8 поддерживает русский язык)
bytes_data = text.encode('utf-8')
# Преобразуем каждый байт в 8-битную строку и объединяем
bits = ''.join(format(byte, '08b') for byte in bytes_data)
return bits
def bits_to_text(bits: str) -> str:
"""
Преобразует строку битов обратно в текст.
Аргументы:
bits (str): Строка из '0' и '1' (длина должна быть кратна 8)
Возвращает:
str: Декодированный текст
Пример:
>>> bits_to_text("01000001")
'A'
"""
# Проверяем, что длина строки кратна 8
if len(bits) % 8 != 0:
raise ValueError("Длина битовой строки должна быть кратна 8")
# Разбиваем строку на блоки по 8 бит и преобразуем в байты
bytes_data = bytearray()
for i in range(0, len(bits), 8):
byte = bits[i:i + 8] # берем 8 бит
bytes_data.append(int(byte, 2)) # преобразуем из двоичной в число
# Декодируем байты в строку (UTF-8)
return bytes_data.decode('utf-8')
def calculate_psnr(original_path: str, modified_path: str) -> float:
"""
Вычисляет PSNR (Peak Signal-to-Noise Ratio) между двумя изображениями.
PSNR показывает, насколько сильно изменилось изображение после внедрения.
Чем выше значение, тем меньше изменений.
- PSNR > 40 dB: отличное качество (изменения практически незаметны)
- PSNR 30-40 dB: хорошее качество
- PSNR 20-30 dB: заметные искажения
- PSNR < 20 dB: сильные искажения
Аргументы:
original_path (str): Путь к исходному изображению
modified_path (str): Путь к измененному изображению
Возвращает:
float: Значение PSNR в децибелах (dB)
"""
from PIL import Image
# Загружаем изображения
img1 = Image.open(original_path).convert('RGB')
img2 = Image.open(modified_path).convert('RGB')
# Преобразуем в массивы numpy
img1_array = np.array(img1, dtype=np.float64)
img2_array = np.array(img2, dtype=np.float64)
# Вычисляем среднеквадратичную ошибку (MSE)
mse = np.mean((img1_array - img2_array) ** 2)
# Если MSE = 0, изображения идентичны
if mse == 0:
return float('inf')
# Максимальное значение пикселя (для RGB это 255)
max_pixel = 255.0
# Формула PSNR: 10 * log10(MAX^2 / MSE)
psnr = 10 * log10((max_pixel ** 2) / mse)
return psnr
def calculate_capacity(image_path: str) -> int:
"""
Рассчитывает максимальную вместимость изображения в байтах для LSB метода.
Для LSB: каждый пиксель (RGB) = 3 бита = 0.375 байта.
Аргументы:
image_path (str): Путь к изображению
Возвращает:
int: Максимальное количество байт, которое можно спрятать
"""
from PIL import Image
img = Image.open(image_path)
width, height = img.size
total_pixels = width * height
# 3 бита на пиксель, переводим в байты
max_bits = total_pixels * 3
max_bytes = max_bits // 8
return max_bytes