""" Модуль LSB (Least Significant Bit) стеганографии. Поддержка цветных изображений и русских текстов. """ import numpy as np from PIL import Image from .utils import text_to_bits, bits_to_text def encode_lsb(image_path: str, message: str, output_path: str) -> bool: """Скрывает сообщение в изображении методом LSB.""" img = Image.open(image_path).convert('RGB') pixels = np.array(img, dtype=np.uint8) height, width, channels = pixels.shape # Формат: [длина сообщения: 32 бита] + [сообщение] msg_bytes = message.encode('utf-8') msg_length = len(msg_bytes) length_bits = format(msg_length, '032b') message_bits = text_to_bits(message) all_bits = length_bits + message_bits bit_list = [int(b) for b in all_bits] total_bits = len(bit_list) # Проверка вместимости max_bits = height * width * channels if total_bits > max_bits: print(f"Ошибка: сообщение слишком большое.") print(f"Доступно: {max_bits} бит, требуется: {total_bits}") return False # Внедрение битов bit_index = 0 for i in range(height): for j in range(width): for c in range(channels): if bit_index >= total_bits: break pixel_value = pixels[i, j, c] bit = bit_list[bit_index] pixels[i, j, c] = (pixel_value & 0xFE) | bit bit_index += 1 if bit_index >= total_bits: break if bit_index >= total_bits: break result_img = Image.fromarray(pixels, mode='RGB') result_img.save(output_path) print(f"Успешно! Спрятано {total_bits} бит ({total_bits // 8} байт)") return True def decode_lsb(image_path: str) -> str: """Извлекает сообщение из изображения методом LSB.""" img = Image.open(image_path).convert('RGB') pixels = np.array(img, dtype=np.uint8) height, width, channels = pixels.shape # Извлекаем все биты all_bits = [] for i in range(height): for j in range(width): for c in range(channels): all_bits.append(pixels[i, j, c] & 1) # Читаем длину сообщения (первые 32 бита) if len(all_bits) < 32: return "" length_bits = all_bits[:32] length_str = ''.join(str(b) for b in length_bits) msg_length = int(length_str, 2) # Проверяем, что длина разумная if msg_length > (len(all_bits) - 32) // 8: return "" # Читаем сообщение message_bits = all_bits[32:32 + msg_length * 8] # Дополняем до кратности 8 (на всякий случай) remainder = len(message_bits) % 8 if remainder != 0: message_bits.extend([0] * (8 - remainder)) if len(message_bits) == 0: return "" bits_string = ''.join(str(b) for b in message_bits) try: return bits_to_text(bits_string) except Exception as e: print(f"Ошибка при декодировании: {e}") return ""