Skip to content

HammingStegano

stegobox.codec.HammingStegano

Bases: BaseCodec

This algorithm allows to conceal str inside image, using Hamming codes to error correct steganographically encoded data.

Originally implemented in DakotaNelson/hamming-stego

Source code in stegobox/codec/hamming_stegano/hamming_stegano.py
class HammingStegano(BaseCodec):
    """This algorithm allows to conceal str inside image,
    using Hamming codes to error correct steganographically encoded data.

    Originally implemented in
    [DakotaNelson/hamming-stego](https://github.com/DakotaNelson/hamming-stego)
    """

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

    def encode(
        self, carrier: Image.Image, payload: str
    ) -> tuple[Image.Image, Image.Image, int]:
        """Encoder requires carrier to be a image and payload to be a string.
           Encode our original message using hamming(8,4).
           Insert our message into the image, then blur the image to simulate
           compression/transmission/general data loss.

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

        Returns:
            img_message: The image with the payload embedded.
            img_blurred: Blur the image to simulate data loss.
            payload_len: The length of payload.
        """
        # encode our original message using hamming(8,4)
        original_message = payload
        original_message_bin = hm.str_to_bin(original_message)

        encoded_message = hm.encodeh(original_message_bin)

        # open up the image we want to use and get it ready to put data in
        img = carrier
        img = img.resize((256, 256), Image.ANTIALIAS)
        img = np.asarray(img)

        # insert our message into the image, then blur the image to simulate
        # compression/transmission/general data loss
        img_with_message = st.insert(img, encoded_message)

        img_message = Image.fromarray(img_with_message)
        #  im.save("image_steg.bmp")

        blur_the_image = True  # change this to not blur the image
        if blur_the_image:
            blurred_img = bl.randomize(img_with_message)
        else:
            blurred_img = img_with_message

        img_blurred = Image.fromarray(blurred_img)
        #  im.save("image_blurred.bmp")
        payload_len = len(payload)
        return img_message, img_blurred, payload_len

    def decode(self, _):
        raise NotImplementedError("This codec does not support decoding without length")

    def decode_with_len(self, carrier: Image.Image, payload_len: int) -> str:
        """Decode the secret payload from the carrier image.
            extract the message (with errors) from the message, find out what
            the errors are thanks to hamming, and generate an error syndrome.
            (basically an array that says "here's where the errors are")

        Args:
            carrier: Carrier image. Read with `stegobox.io.image.read()`.
            payload_len: The length of payload.

        Returns:
            decoded_str: The decoded payload (secret message).

        """
        # extract the message (with errors) from the message, find out what
        # the errors are thanks to hamming, and generate an error syndrome
        # (basically an array that says "here's where the errors are")
        img = carrier
        blurred_img = np.asarray(img)
        extracted_msg = st.extract(blurred_img)
        decoded = hm.decodeh(extracted_msg)
        decoded_str = hm.bin_to_str(decoded)
        return decoded_str[0:payload_len]

encode(carrier, payload)

Encoder requires carrier to be a image and payload to be a string. Encode our original message using hamming(8,4). Insert our message into the image, then blur the image to simulate compression/transmission/general data loss.

Parameters:

Name Type Description Default
carrier Image

Carrier image. Read with stegobox.io.image.read().

required
payload str

Payload (secret message) to be encoded.

required

Returns:

Name Type Description
img_message Image

The image with the payload embedded.

img_blurred Image

Blur the image to simulate data loss.

payload_len int

The length of payload.

Source code in stegobox/codec/hamming_stegano/hamming_stegano.py
def encode(
    self, carrier: Image.Image, payload: str
) -> tuple[Image.Image, Image.Image, int]:
    """Encoder requires carrier to be a image and payload to be a string.
       Encode our original message using hamming(8,4).
       Insert our message into the image, then blur the image to simulate
       compression/transmission/general data loss.

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

    Returns:
        img_message: The image with the payload embedded.
        img_blurred: Blur the image to simulate data loss.
        payload_len: The length of payload.
    """
    # encode our original message using hamming(8,4)
    original_message = payload
    original_message_bin = hm.str_to_bin(original_message)

    encoded_message = hm.encodeh(original_message_bin)

    # open up the image we want to use and get it ready to put data in
    img = carrier
    img = img.resize((256, 256), Image.ANTIALIAS)
    img = np.asarray(img)

    # insert our message into the image, then blur the image to simulate
    # compression/transmission/general data loss
    img_with_message = st.insert(img, encoded_message)

    img_message = Image.fromarray(img_with_message)
    #  im.save("image_steg.bmp")

    blur_the_image = True  # change this to not blur the image
    if blur_the_image:
        blurred_img = bl.randomize(img_with_message)
    else:
        blurred_img = img_with_message

    img_blurred = Image.fromarray(blurred_img)
    #  im.save("image_blurred.bmp")
    payload_len = len(payload)
    return img_message, img_blurred, payload_len

decode_with_len(carrier, payload_len)

Decode the secret payload from the carrier image. extract the message (with errors) from the message, find out what the errors are thanks to hamming, and generate an error syndrome. (basically an array that says "here's where the errors are")

Parameters:

Name Type Description Default
carrier Image

Carrier image. Read with stegobox.io.image.read().

required
payload_len int

The length of payload.

required

Returns:

Name Type Description
decoded_str str

The decoded payload (secret message).

Source code in stegobox/codec/hamming_stegano/hamming_stegano.py
def decode_with_len(self, carrier: Image.Image, payload_len: int) -> str:
    """Decode the secret payload from the carrier image.
        extract the message (with errors) from the message, find out what
        the errors are thanks to hamming, and generate an error syndrome.
        (basically an array that says "here's where the errors are")

    Args:
        carrier: Carrier image. Read with `stegobox.io.image.read()`.
        payload_len: The length of payload.

    Returns:
        decoded_str: The decoded payload (secret message).

    """
    # extract the message (with errors) from the message, find out what
    # the errors are thanks to hamming, and generate an error syndrome
    # (basically an array that says "here's where the errors are")
    img = carrier
    blurred_img = np.asarray(img)
    extracted_msg = st.extract(blurred_img)
    decoded = hm.decodeh(extracted_msg)
    decoded_str = hm.bin_to_str(decoded)
    return decoded_str[0:payload_len]