From 3103a3ae9bb0b77d32c28c3a45d034a47855c79d Mon Sep 17 00:00:00 2001 From: Flavien Date: Fri, 11 Nov 2022 12:15:25 +0100 Subject: [PATCH] Merge lsb and lsbset modules --- bin/lsbset.py | 8 +-- stegano/__init__.py | 1 - stegano/{lsbset => lsb}/generators.py | 4 +- stegano/lsb/lsb.py | 64 +++++++++++++-------- stegano/lsbset/__init__.py | 4 -- stegano/lsbset/lsbset.py | 83 --------------------------- tests/test_generators.py | 4 +- 7 files changed, 48 insertions(+), 120 deletions(-) rename stegano/{lsbset => lsb}/generators.py (98%) mode change 100755 => 100644 stegano/lsb/lsb.py delete mode 100644 stegano/lsbset/__init__.py delete mode 100644 stegano/lsbset/lsbset.py diff --git a/bin/lsbset.py b/bin/lsbset.py index ffba1a0..95eb41d 100755 --- a/bin/lsbset.py +++ b/bin/lsbset.py @@ -29,8 +29,8 @@ import inspect import crayons try: - from stegano import lsbset - from stegano.lsbset import generators + from stegano import lsb + from stegano.lsb import generators except Exception: print("Install stegano: pipx install Stegano") @@ -185,7 +185,7 @@ def main(): elif arguments.secret_file != "": secret = tools.binary2base64(arguments.secret_file) - img_encoded = lsbset.hide( + img_encoded = lsb.hide( arguments.input_image_file, secret, generator, int(arguments.shift) ) try: @@ -196,7 +196,7 @@ def main(): elif arguments.command == "reveal": try: - secret = lsbset.reveal( + secret = lsb.reveal( arguments.input_image_file, generator, int(arguments.shift) ) except IndexError: diff --git a/stegano/__init__.py b/stegano/__init__.py index c76943b..4bca0e9 100755 --- a/stegano/__init__.py +++ b/stegano/__init__.py @@ -4,6 +4,5 @@ from . import red from . import exifHeader from . import lsb -from . import lsbset from . import steganalysis diff --git a/stegano/lsbset/generators.py b/stegano/lsb/generators.py similarity index 98% rename from stegano/lsbset/generators.py rename to stegano/lsb/generators.py index c450afe..ea822c3 100644 --- a/stegano/lsbset/generators.py +++ b/stegano/lsb/generators.py @@ -29,7 +29,7 @@ import itertools import cv2 import numpy as np import math -from typing import Dict, Iterator, List, Any, Union +from typing import Dict, Iterator, List, Any def identity() -> Iterator[int]: @@ -225,7 +225,7 @@ def LFSR(m: int) -> Iterator[int]: # Add the feedback bit state.insert(0, feedback) # Convert the registers to an int - out = sum([e * (2 ** i) for i, e in enumerate(state)]) + out = sum([e * (2**i) for i, e in enumerate(state)]) yield out diff --git a/stegano/lsb/lsb.py b/stegano/lsb/lsb.py old mode 100755 new mode 100644 index ee5ff3a..6dc670d --- a/stegano/lsb/lsb.py +++ b/stegano/lsb/lsb.py @@ -20,55 +20,71 @@ # along with this program. If not, see __author__ = "Cedric Bonhomme" -__version__ = "$Revision: 0.4 $" -__date__ = "$Date: 2016/08/04 $" -__revision__ = "$Date: 2019/06/01 $" +__version__ = "$Revision: 0.7 $" +__date__ = "$Date: 2016/03/13 $" +__revision__ = "$Date: 2019/05/31 $" __license__ = "GPLv3" -from typing import IO, Union +from typing import IO, Iterator, Union +from .generators import identity from stegano import tools def hide( image: Union[str, IO[bytes]], message: str, - encoding: str = "UTF-8", + generator: Iterator[int] = None, shift: int = 0, + encoding: str = "UTF-8", auto_convert_rgb: bool = False, ): """Hide a message (string) in an image with the LSB (Least Significant Bit) technique. """ hider = tools.Hider(image, message, encoding, auto_convert_rgb) - width, height = hider.encoded_image.size + width = hider.encoded_image.width - for row in range(height): - for col in range(width): - if shift != 0: - shift -= 1 - continue + if not generator: + generator = identity() - if hider.encode_another_pixel(): - hider.encode_pixel((col, row)) - else: - return hider.encoded_image + while shift != 0: + next(generator) + shift -= 1 + + while hider.encode_another_pixel(): + generated_number = next(generator) + + col = generated_number % width + row = int(generated_number / width) + + hider.encode_pixel((col, row)) + + return hider.encoded_image def reveal( encoded_image: Union[str, IO[bytes]], - encoding: str = "UTF-8", + generator: Iterator[int] = None, shift: int = 0, + encoding: str = "UTF-8", ): """Find a message in an image (with the LSB technique).""" revealer = tools.Revealer(encoded_image, encoding) - width, height = revealer.encoded_image.size + width = revealer.encoded_image.width - for row in range(height): - for col in range(width): - if shift != 0: - shift -= 1 - continue + if not generator: + generator = identity() - if revealer.decode_pixel((col, row)): - return revealer.secret_message + while shift != 0: + next(generator) + shift -= 1 + + while True: + generated_number = next(generator) + + col = generated_number % width + row = int(generated_number / width) + + if revealer.decode_pixel((col, row)): + return revealer.secret_message diff --git a/stegano/lsbset/__init__.py b/stegano/lsbset/__init__.py deleted file mode 100644 index 22954f0..0000000 --- a/stegano/lsbset/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from .lsbset import * diff --git a/stegano/lsbset/lsbset.py b/stegano/lsbset/lsbset.py deleted file mode 100644 index fcf77d2..0000000 --- a/stegano/lsbset/lsbset.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Stegano - Stegano is a pure Python steganography module. -# Copyright (C) 2010-2022 Cédric Bonhomme - https://www.cedricbonhomme.org -# -# For more information : https://git.sr.ht/~cedric/stegano -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see - -__author__ = "Cedric Bonhomme" -__version__ = "$Revision: 0.7 $" -__date__ = "$Date: 2016/03/13 $" -__revision__ = "$Date: 2019/05/31 $" -__license__ = "GPLv3" - -from typing import IO, Iterator, Union - -from stegano import tools - - -def hide( - image: Union[str, IO[bytes]], - message: str, - generator: Iterator[int], - shift: int = 0, - encoding: str = "UTF-8", - auto_convert_rgb: bool = False, -): - """Hide a message (string) in an image with the - LSB (Least Significant Bit) technique. - """ - hider = tools.Hider(image, message, encoding, auto_convert_rgb) - width = hider.encoded_image.width - - while shift != 0: - next(generator) - shift -= 1 - - while hider.encode_another_pixel(): - generated_number = next(generator) - - col = generated_number % width - row = int(generated_number / width) - - hider.encode_pixel((col, row)) - - return hider.encoded_image - - -def reveal( - encoded_image: Union[str, IO[bytes]], - generator: Iterator[int], - shift: int = 0, - encoding: str = "UTF-8", -): - """Find a message in an image (with the LSB technique).""" - revealer = tools.Revealer(encoded_image, encoding) - width = revealer.encoded_image.width - - while shift != 0: - next(generator) - shift -= 1 - - while True: - generated_number = next(generator) - - col = generated_number % width - row = int(generated_number / width) - - if revealer.decode_pixel((col, row)): - return revealer.secret_message diff --git a/tests/test_generators.py b/tests/test_generators.py index 914291c..a7d7309 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -30,7 +30,7 @@ import itertools import cv2 import numpy as np -from stegano.lsbset import generators +from stegano.lsb import generators class TestGenerators(unittest.TestCase): @@ -151,7 +151,7 @@ class TestGenerators(unittest.TestCase): """Test the LFSR generator""" with open("./tests/expected-results/LFSR", "r") as f: self.assertEqual( - tuple(itertools.islice(generators.LFSR(2 ** 8), 256)), + tuple(itertools.islice(generators.LFSR(2**8), 256)), tuple(int(line) for line in f), )