mirror of
https://github.com/cedricbonhomme/Stegano.git
synced 2025-05-12 17:18:30 +02:00
Merge lsb and lsbset modules
This commit is contained in:
parent
0d98e1834c
commit
3103a3ae9b
7 changed files with 48 additions and 120 deletions
|
@ -29,8 +29,8 @@ import inspect
|
||||||
import crayons
|
import crayons
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from stegano import lsbset
|
from stegano import lsb
|
||||||
from stegano.lsbset import generators
|
from stegano.lsb import generators
|
||||||
except Exception:
|
except Exception:
|
||||||
print("Install stegano: pipx install Stegano")
|
print("Install stegano: pipx install Stegano")
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ def main():
|
||||||
elif arguments.secret_file != "":
|
elif arguments.secret_file != "":
|
||||||
secret = tools.binary2base64(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)
|
arguments.input_image_file, secret, generator, int(arguments.shift)
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
@ -196,7 +196,7 @@ def main():
|
||||||
|
|
||||||
elif arguments.command == "reveal":
|
elif arguments.command == "reveal":
|
||||||
try:
|
try:
|
||||||
secret = lsbset.reveal(
|
secret = lsb.reveal(
|
||||||
arguments.input_image_file, generator, int(arguments.shift)
|
arguments.input_image_file, generator, int(arguments.shift)
|
||||||
)
|
)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
|
|
@ -4,6 +4,5 @@
|
||||||
from . import red
|
from . import red
|
||||||
from . import exifHeader
|
from . import exifHeader
|
||||||
from . import lsb
|
from . import lsb
|
||||||
from . import lsbset
|
|
||||||
|
|
||||||
from . import steganalysis
|
from . import steganalysis
|
||||||
|
|
|
@ -29,7 +29,7 @@ import itertools
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import math
|
import math
|
||||||
from typing import Dict, Iterator, List, Any, Union
|
from typing import Dict, Iterator, List, Any
|
||||||
|
|
||||||
|
|
||||||
def identity() -> Iterator[int]:
|
def identity() -> Iterator[int]:
|
||||||
|
@ -225,7 +225,7 @@ def LFSR(m: int) -> Iterator[int]:
|
||||||
# Add the feedback bit
|
# Add the feedback bit
|
||||||
state.insert(0, feedback)
|
state.insert(0, feedback)
|
||||||
# Convert the registers to an int
|
# 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
|
yield out
|
||||||
|
|
||||||
|
|
52
stegano/lsb/lsb.py
Executable file → Normal file
52
stegano/lsb/lsb.py
Executable file → Normal file
|
@ -20,55 +20,71 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
__author__ = "Cedric Bonhomme"
|
__author__ = "Cedric Bonhomme"
|
||||||
__version__ = "$Revision: 0.4 $"
|
__version__ = "$Revision: 0.7 $"
|
||||||
__date__ = "$Date: 2016/08/04 $"
|
__date__ = "$Date: 2016/03/13 $"
|
||||||
__revision__ = "$Date: 2019/06/01 $"
|
__revision__ = "$Date: 2019/05/31 $"
|
||||||
__license__ = "GPLv3"
|
__license__ = "GPLv3"
|
||||||
|
|
||||||
from typing import IO, Union
|
from typing import IO, Iterator, Union
|
||||||
|
|
||||||
|
from .generators import identity
|
||||||
from stegano import tools
|
from stegano import tools
|
||||||
|
|
||||||
|
|
||||||
def hide(
|
def hide(
|
||||||
image: Union[str, IO[bytes]],
|
image: Union[str, IO[bytes]],
|
||||||
message: str,
|
message: str,
|
||||||
encoding: str = "UTF-8",
|
generator: Iterator[int] = None,
|
||||||
shift: int = 0,
|
shift: int = 0,
|
||||||
|
encoding: str = "UTF-8",
|
||||||
auto_convert_rgb: bool = False,
|
auto_convert_rgb: bool = False,
|
||||||
):
|
):
|
||||||
"""Hide a message (string) in an image with the
|
"""Hide a message (string) in an image with the
|
||||||
LSB (Least Significant Bit) technique.
|
LSB (Least Significant Bit) technique.
|
||||||
"""
|
"""
|
||||||
hider = tools.Hider(image, message, encoding, auto_convert_rgb)
|
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):
|
if not generator:
|
||||||
for col in range(width):
|
generator = identity()
|
||||||
if shift != 0:
|
|
||||||
|
while shift != 0:
|
||||||
|
next(generator)
|
||||||
shift -= 1
|
shift -= 1
|
||||||
continue
|
|
||||||
|
|
||||||
if hider.encode_another_pixel():
|
while hider.encode_another_pixel():
|
||||||
|
generated_number = next(generator)
|
||||||
|
|
||||||
|
col = generated_number % width
|
||||||
|
row = int(generated_number / width)
|
||||||
|
|
||||||
hider.encode_pixel((col, row))
|
hider.encode_pixel((col, row))
|
||||||
else:
|
|
||||||
return hider.encoded_image
|
return hider.encoded_image
|
||||||
|
|
||||||
|
|
||||||
def reveal(
|
def reveal(
|
||||||
encoded_image: Union[str, IO[bytes]],
|
encoded_image: Union[str, IO[bytes]],
|
||||||
encoding: str = "UTF-8",
|
generator: Iterator[int] = None,
|
||||||
shift: int = 0,
|
shift: int = 0,
|
||||||
|
encoding: str = "UTF-8",
|
||||||
):
|
):
|
||||||
"""Find a message in an image (with the LSB technique)."""
|
"""Find a message in an image (with the LSB technique)."""
|
||||||
revealer = tools.Revealer(encoded_image, encoding)
|
revealer = tools.Revealer(encoded_image, encoding)
|
||||||
width, height = revealer.encoded_image.size
|
width = revealer.encoded_image.width
|
||||||
|
|
||||||
for row in range(height):
|
if not generator:
|
||||||
for col in range(width):
|
generator = identity()
|
||||||
if shift != 0:
|
|
||||||
|
while shift != 0:
|
||||||
|
next(generator)
|
||||||
shift -= 1
|
shift -= 1
|
||||||
continue
|
|
||||||
|
while True:
|
||||||
|
generated_number = next(generator)
|
||||||
|
|
||||||
|
col = generated_number % width
|
||||||
|
row = int(generated_number / width)
|
||||||
|
|
||||||
if revealer.decode_pixel((col, row)):
|
if revealer.decode_pixel((col, row)):
|
||||||
return revealer.secret_message
|
return revealer.secret_message
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from .lsbset import *
|
|
|
@ -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 <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
__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
|
|
|
@ -30,7 +30,7 @@ import itertools
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from stegano.lsbset import generators
|
from stegano.lsb import generators
|
||||||
|
|
||||||
|
|
||||||
class TestGenerators(unittest.TestCase):
|
class TestGenerators(unittest.TestCase):
|
||||||
|
@ -151,7 +151,7 @@ class TestGenerators(unittest.TestCase):
|
||||||
"""Test the LFSR generator"""
|
"""Test the LFSR generator"""
|
||||||
with open("./tests/expected-results/LFSR", "r") as f:
|
with open("./tests/expected-results/LFSR", "r") as f:
|
||||||
self.assertEqual(
|
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),
|
tuple(int(line) for line in f),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue