Skip to content

LSBWavRep

stegobox.codec.LSBWavRep

Bases: BaseCodec

This module implements simple LSB replacement steganography in WAV audios.

with code shamelessly taken from techchipnet/HiddenWave

Source code in stegobox/codec/lsb_wav_rep.py
class LSBWavRep(BaseCodec):
    """
    This module implements simple LSB replacement steganography in WAV audios.

    with code shamelessly taken from
    [techchipnet/HiddenWave](https://github.com/techchipnet/HiddenWave)
    """

    def __init__(self) -> None:
        super().__init__()

    def encode(
        self, carrier: wave.Wave_read, payload: str
    ) -> tuple[bytes, wave._wave_params]:
        """Encoder requires the carrier audio to be WAV and the payload to be a string.

        Args:
            carrier: Carrier audio in format WAV. Read with `stegobox.io.audio.read()`.
            payload: Payload (secret message) to be encoded.

        Returns:
            bytes: Frame information in bytes of the audio with the payload embedded.
            wave._wave_params: Parameters for audio with the payload embedded.
        """
        self._check_empty_payload(payload)

        # Read audio frame information
        frame_bytes = bytearray(list(carrier.readframes(carrier.getnframes())))
        string = payload + int((len(frame_bytes) - (len(payload) * 8)) / 8) * "#"
        bits = list(
            map(int, "".join([bin(ord(i)).lstrip("0b").rjust(8, "0") for i in string]))
        )
        for i, bit in enumerate(bits):
            frame_bytes[i] = (frame_bytes[i] & 254) | bit
        frame_modified = bytes(frame_bytes)

        return bytes(frame_modified), carrier.getparams()

    def decode(self, carrier: wave.Wave_read) -> str:
        """Decode the secret payload from the carrier audio

        Args:
            carrier: Carrier audio in format WAV. Read with `stegobox.io.audio.read()`.

        Returns:
            str: The decoded payload (secret message).
        """
        # Read audio frame information
        frame_bytes = bytearray(list(carrier.readframes(carrier.getnframes())))
        extracted = [frame_bytes[i] & 1 for i in range(len(frame_bytes))]
        string = "".join(
            chr(int("".join(map(str, extracted[i : i + 8])), 2))
            for i in range(0, len(extracted), 8)
        )
        msg = string.split("###")[0]

        return msg

    def _check_empty_payload(self, payload: str) -> None:
        if not payload:
            raise Exception("Payload must not be empty.")

encode(carrier, payload)

Encoder requires the carrier audio to be WAV and the payload to be a string.

Parameters:

Name Type Description Default
carrier Wave_read

Carrier audio in format WAV. Read with stegobox.io.audio.read().

required
payload str

Payload (secret message) to be encoded.

required

Returns:

Name Type Description
bytes bytes

Frame information in bytes of the audio with the payload embedded.

_wave_params

wave._wave_params: Parameters for audio with the payload embedded.

Source code in stegobox/codec/lsb_wav_rep.py
def encode(
    self, carrier: wave.Wave_read, payload: str
) -> tuple[bytes, wave._wave_params]:
    """Encoder requires the carrier audio to be WAV and the payload to be a string.

    Args:
        carrier: Carrier audio in format WAV. Read with `stegobox.io.audio.read()`.
        payload: Payload (secret message) to be encoded.

    Returns:
        bytes: Frame information in bytes of the audio with the payload embedded.
        wave._wave_params: Parameters for audio with the payload embedded.
    """
    self._check_empty_payload(payload)

    # Read audio frame information
    frame_bytes = bytearray(list(carrier.readframes(carrier.getnframes())))
    string = payload + int((len(frame_bytes) - (len(payload) * 8)) / 8) * "#"
    bits = list(
        map(int, "".join([bin(ord(i)).lstrip("0b").rjust(8, "0") for i in string]))
    )
    for i, bit in enumerate(bits):
        frame_bytes[i] = (frame_bytes[i] & 254) | bit
    frame_modified = bytes(frame_bytes)

    return bytes(frame_modified), carrier.getparams()

decode(carrier)

Decode the secret payload from the carrier audio

Parameters:

Name Type Description Default
carrier Wave_read

Carrier audio in format WAV. Read with stegobox.io.audio.read().

required

Returns:

Name Type Description
str str

The decoded payload (secret message).

Source code in stegobox/codec/lsb_wav_rep.py
def decode(self, carrier: wave.Wave_read) -> str:
    """Decode the secret payload from the carrier audio

    Args:
        carrier: Carrier audio in format WAV. Read with `stegobox.io.audio.read()`.

    Returns:
        str: The decoded payload (secret message).
    """
    # Read audio frame information
    frame_bytes = bytearray(list(carrier.readframes(carrier.getnframes())))
    extracted = [frame_bytes[i] & 1 for i in range(len(frame_bytes))]
    string = "".join(
        chr(int("".join(map(str, extracted[i : i + 8])), 2))
        for i in range(0, len(extracted), 8)
    )
    msg = string.split("###")[0]

    return msg