Ejemplo n.º 1
0
def recover_message_from_image(input_image, num_lsb):
    """Returns the message from the steganographed image"""
    start = time()
    if isinstance(input_image, Image.Image):
        steg_image = input_image
    else:
        steg_image = Image.open(input_image)

    color_data = [v for t in steg_image.getdata() for v in t]

    file_size_tag_size = bytes_in_max_file_size(steg_image, num_lsb)
    tag_bit_height = roundup(8 * file_size_tag_size / num_lsb)

    bytes_to_recover = int.from_bytes(
        lsb_deinterleave_list(color_data[:tag_bit_height],
                              8 * file_size_tag_size, num_lsb),
        byteorder=sys.byteorder,
    )
    log.debug(f"Files read".ljust(30) + f" in {time() - start:.2f}s")

    start = time()
    data = lsb_deinterleave_list(color_data[tag_bit_height:],
                                 8 * bytes_to_recover, num_lsb)
    log.debug(f"{bytes_to_recover} bytes recovered".ljust(30) +
              f" in {time() - start:.2f}s")
    return data
Ejemplo n.º 2
0
def recover_message_from_image(input_image, num_lsb):
    """Returns the message from the steganographed image"""
    start = time()
    if isinstance(input_image, Image.Image):
        steg_image = input_image
    else:
        steg_image = Image.open(input_image)

    color_data = [v for t in steg_image.getdata() for v in t]

    file_size_tag_size = bytes_in_max_file_size(steg_image, num_lsb)
    tag_bit_height = roundup(8 * file_size_tag_size / num_lsb)

    bytes_to_recover = int.from_bytes(
        lsb_deinterleave_list(color_data[:tag_bit_height],
                              8 * file_size_tag_size, num_lsb),
        byteorder=sys.byteorder,
    )

    maximum_bytes_in_image = num_lsb * len(color_data[tag_bit_height:]) // 8
    if bytes_to_recover > maximum_bytes_in_image:
        raise ValueError(
            f"This image appears to be corrupted.\n" +
            f"It claims to hold {bytes_to_recover} B, " +
            f"but can only hold {maximum_bytes_in_image} B with {num_lsb} LSBs"
        )

    log.debug(f"Files read".ljust(30) + f" in {time() - start:.2f}s")

    start = time()
    data = lsb_deinterleave_list(color_data[tag_bit_height:],
                                 8 * bytes_to_recover, num_lsb)
    log.debug(f"{bytes_to_recover} bytes recovered".ljust(30) +
              f" in {time() - start:.2f}s")
    return data
Ejemplo n.º 3
0
    def test_random_interleaving(self, num_trials=256, filename_length=5):
        filename = "".join(
            choice(string.ascii_lowercase) for _ in range(filename_length)
        )
        png_input_filename = filename + ".png"
        payload_input_filename = filename + ".txt"
        png_output_filename = filename + "_steg.png"
        payload_output_filename = filename + "_recovered.txt"

        np.random.seed(0)
        for _ in range(num_trials):
            width = np.random.randint(1, 256)
            height = np.random.randint(1, 256)
            num_lsb = np.random.randint(1, 9)

            file_size_tag_length = roundup(
                int(3 * width * height * num_lsb).bit_length() / 8
            )
            payload_len = (3 * width * height * num_lsb - 8 * file_size_tag_length) // 8

            if payload_len < 0:
                continue

            self.write_random_image(png_input_filename, width=width, height=height)
            self.write_random_file(payload_input_filename, num_bytes=payload_len)

            try:
                hide_data(
                    png_input_filename,
                    payload_input_filename,
                    png_output_filename,
                    num_lsb,
                    compression_level=1,
                )
                recover_data(png_output_filename, payload_output_filename, num_lsb)
            except ValueError as e:
                os.remove(png_input_filename)
                os.remove(payload_input_filename)
                os.remove(png_output_filename)
                os.remove(payload_output_filename)
                raise e

            with open(payload_input_filename, "rb") as input_file, open(
                    payload_output_filename, "rb"
            ) as output_file:
                input_payload_data = input_file.read()
                output_payload_data = output_file.read()

            os.remove(png_input_filename)
            os.remove(payload_input_filename)
            os.remove(png_output_filename)
            os.remove(payload_output_filename)

            self.assertEqual(input_payload_data, output_payload_data)
Ejemplo n.º 4
0
def bytes_in_max_file_size(image, num_lsb):
    """Returns the number of bits needed to store the size of the file."""
    return roundup(max_bits_to_hide(image, num_lsb).bit_length() / 8)