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)