Прописал код для core/utils.py
Добавлены вспомогательные функции для стеганографии LSB и DCT
This commit is contained in:
128
core/utils.py
128
core/utils.py
@@ -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
|
||||||
Reference in New Issue
Block a user