#!/usr/bin/env python3 # -*- coding: utf-8 -*- import wave import struct import zlib import numpy as np SR = 44100 SKIP_SEC = 1.0 STEP = 2 IN_WAV = "some_secret.wav" def read_wav_int16(path: str): with wave.open(path, "rb") as wf: assert wf.getnchannels() == 2 assert wf.getsampwidth() == 2 sr = wf.getframerate() frames = wf.readframes(wf.getnframes()) arr = np.frombuffer(frames, dtype=np.int16).reshape(-1, 2) return sr, arr def bits_to_bytes_big_endian(bits: np.ndarray) -> bytes: # Длина должна быть кратна 8 n = (bits.size + 7) // 8 * 8 if n != bits.size: bits = np.pad(bits, (0, n - bits.size), constant_values=0) by = np.packbits(bits.astype(np.uint8), bitorder='big').tobytes() return by def extract_header_and_length(right: np.ndarray, sr: int): skip = int(sr * SKIP_SEC) # Считываем первые 12 байт (заголовок: 4 + 4 + 4) header_bits_count = 12 * 8 idxs = skip + np.arange(header_bits_count) * STEP bits = (right[idxs] & 1).astype(np.uint8) header = bits_to_bytes_big_endian(bits) magic = header[:4] if magic != b"STAG": raise ValueError("Магия заголовка не совпала — это не тот контейнер.") length = struct.unpack(">I", header[4:8])[0] crc = struct.unpack(">I", header[8:12])[0] return length, crc def extract_all(sr: int, stereo: np.ndarray): right = stereo[:, 1] length, crc_expected = extract_header_and_length(right, sr) total_bytes = 12 + length total_bits = total_bytes * 8 skip = int(sr * SKIP_SEC) idxs = skip + np.arange(total_bits) * STEP bits = (right[idxs] & 1).astype(np.uint8) data = bits_to_bytes_big_endian(bits) header = data[:12] payload = data[12:12+length] crc_actual = zlib.crc32(payload) & 0xFFFFFFFF if crc_actual != crc_expected: raise ValueError("CRC не сошлась — данные повреждены или неверные параметры извлечения.") flag = zlib.decompress(payload).decode("utf-8") return flag def main(): sr, stereo = read_wav_int16(IN_WAV) flag = extract_all(sr, stereo) print("[+] DATA [ ", flag, " ]") if __name__ == "__main__": main()