mirror of
https://github.com/cedricbonhomme/Stegano.git
synced 2025-05-12 17:18:30 +02:00
added a shift parameter for the lsbset module.
This commit is contained in:
parent
a86361dd27
commit
ea2de8142c
6 changed files with 47 additions and 15 deletions
|
@ -1,6 +1,11 @@
|
|||
Release History
|
||||
===============
|
||||
|
||||
0.9.0 (2018-12-18)
|
||||
------------------
|
||||
|
||||
* added the possibility to shift the encoded bits when using the lsbset module.
|
||||
|
||||
0.8.6 (2018-11-05)
|
||||
------------------
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ parser_hide.add_argument("-g", "--generator", dest="generator_function",
|
|||
choices=[generator[0] for generator in \
|
||||
inspect.getmembers(generators, inspect.isfunction)],
|
||||
required=True, help="Generator")
|
||||
parser_hide.add_argument("-s", "--shift", dest="shift",
|
||||
default=0, help="Shift for the generator")
|
||||
|
||||
group_secret = parser_hide.add_mutually_exclusive_group(required=True)
|
||||
# Non binary secret message to hide
|
||||
|
@ -81,6 +83,8 @@ parser_reveal.add_argument("-g", "--generator", dest="generator_function",
|
|||
choices=[generator[0] for generator in \
|
||||
inspect.getmembers(generators, inspect.isfunction)],
|
||||
required=True, help="Generator")
|
||||
parser_reveal.add_argument("-s", "--shift", dest="shift",
|
||||
default=0, help="Shift for the generator")
|
||||
parser_reveal.add_argument("-o", dest="secret_binary",
|
||||
help="Output for the binary secret (Text or any binary file).")
|
||||
|
||||
|
@ -111,7 +115,8 @@ if arguments.command == 'hide':
|
|||
elif arguments.secret_file != "":
|
||||
secret = tools.binary2base64(arguments.secret_file)
|
||||
|
||||
img_encoded = lsbset.hide(arguments.input_image_file, secret, generator)
|
||||
img_encoded = lsbset.hide(arguments.input_image_file, secret, generator,
|
||||
int(arguments.shift))
|
||||
try:
|
||||
img_encoded.save(arguments.output_image_file)
|
||||
except Exception as e:
|
||||
|
@ -120,7 +125,8 @@ if arguments.command == 'hide':
|
|||
|
||||
elif arguments.command == 'reveal':
|
||||
try:
|
||||
secret = lsbset.reveal(arguments.input_image_file, generator)
|
||||
secret = lsbset.reveal(arguments.input_image_file, generator,
|
||||
int(arguments.shift))
|
||||
except IndexError:
|
||||
print("Impossible to detect message.")
|
||||
exit(0)
|
||||
|
|
2
setup.py
2
setup.py
|
@ -33,7 +33,7 @@ with codecs.open(os.path.join(here, 'CHANGELOG.rst'), encoding='utf-8') as f:
|
|||
|
||||
setup(
|
||||
name='Stegano',
|
||||
version='0.8.6',
|
||||
version='0.9.0',
|
||||
author='Cédric Bonhomme',
|
||||
author_email='cedric@cedricbonhomme.org',
|
||||
packages=packages,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#-*- coding: utf-8 -*-
|
||||
|
||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
||||
# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||
# Copyright (C) 2010-2018 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||
#
|
||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||
#
|
||||
|
@ -20,9 +20,9 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
__author__ = "Cedric Bonhomme"
|
||||
__version__ = "$Revision: 0.5 $"
|
||||
__version__ = "$Revision: 0.6 $"
|
||||
__date__ = "$Date: 2016/03/13 $"
|
||||
__revision__ = "$Date: 2017/05/04 $"
|
||||
__revision__ = "$Date: 2018/12/18 $"
|
||||
__license__ = "GPLv3"
|
||||
|
||||
import sys
|
||||
|
@ -36,6 +36,7 @@ from . import generators
|
|||
def hide(input_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
|
||||
|
@ -68,6 +69,9 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
if len_message_bits > npixels * 3:
|
||||
raise Exception("The message you want to hide is too long: {}". \
|
||||
format(message_length))
|
||||
while shift != 0:
|
||||
next(generator)
|
||||
shift -= 1
|
||||
|
||||
while index + 3 <= len_message_bits :
|
||||
generated_number = next(generator)
|
||||
|
@ -97,6 +101,7 @@ def hide(input_image: Union[str, IO[bytes]],
|
|||
|
||||
def reveal(input_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).
|
||||
"""
|
||||
|
@ -107,6 +112,10 @@ def reveal(input_image: Union[str, IO[bytes]],
|
|||
bitab = []
|
||||
limit = None
|
||||
|
||||
while shift != 0:
|
||||
next(generator)
|
||||
shift -= 1
|
||||
|
||||
while True:
|
||||
generated_number = next(generator)
|
||||
# color = [r, g, b]
|
||||
|
|
|
@ -54,20 +54,20 @@ class TestLSB(unittest.TestCase):
|
|||
def test_hide_and_reveal_UTF32LE(self):
|
||||
messages_to_hide = 'I love 🍕 and 🍫!'
|
||||
secret = lsb.hide("./tests/sample-files/Lenna.png",
|
||||
messages_to_hide, 'UTF-32LE')
|
||||
messages_to_hide, encoding='UTF-32LE')
|
||||
secret.save("./image.png")
|
||||
|
||||
clear_message = lsb.reveal("./image.png", 'UTF-32LE')
|
||||
clear_message = lsb.reveal("./image.png", encoding='UTF-32LE')
|
||||
self.assertEqual(messages_to_hide, clear_message)
|
||||
|
||||
def test_with_transparent_png(self):
|
||||
messages_to_hide = ['🍕', 'a', 'foo', 'Hello World!', ':Python:']
|
||||
for message in messages_to_hide:
|
||||
secret = lsb.hide("./tests/sample-files/transparent.png",
|
||||
message, 'UTF-32LE')
|
||||
message, encoding='UTF-32LE')
|
||||
secret.save("./image.png")
|
||||
|
||||
clear_message = lsb.reveal("./image.png", 'UTF-32LE')
|
||||
clear_message = lsb.reveal("./image.png", encoding='UTF-32LE')
|
||||
|
||||
self.assertEqual(message, clear_message)
|
||||
|
||||
|
@ -75,19 +75,19 @@ class TestLSB(unittest.TestCase):
|
|||
def test_manual_convert_rgb(self, input):
|
||||
message_to_hide = 'I love 🍕 and 🍫!'
|
||||
secret = lsb.hide("./tests/sample-files/Lenna-grayscale.png",
|
||||
message_to_hide, 'UTF-32LE')
|
||||
message_to_hide, encoding='UTF-32LE')
|
||||
|
||||
@patch('builtins.input', return_value='n')
|
||||
def test_refuse_convert_rgb(self, input):
|
||||
message_to_hide = 'I love 🍕 and 🍫!'
|
||||
with self.assertRaises(Exception):
|
||||
secret = lsb.hide("./tests/sample-files/Lenna-grayscale.png",
|
||||
message_to_hide, 'UTF-32LE')
|
||||
message_to_hide, encoding='UTF-32LE')
|
||||
|
||||
def test_auto_convert_rgb(self):
|
||||
message_to_hide = 'I love 🍕 and 🍫!'
|
||||
secret = lsb.hide("./tests/sample-files/Lenna-grayscale.png",
|
||||
message_to_hide, 'UTF-32LE', True)
|
||||
message_to_hide, encoding='UTF-32LE', auto_convert_rgb=True)
|
||||
|
||||
def test_with_text_file(self):
|
||||
text_file_to_hide = './tests/sample-files/lorem_ipsum.txt'
|
||||
|
|
|
@ -54,16 +54,28 @@ class TestLSBSet(unittest.TestCase):
|
|||
|
||||
self.assertEqual(message, clear_message)
|
||||
|
||||
def test_hide_and_reveal_with_shift(self):
|
||||
messages_to_hide = ["a", "foo", "Hello World!", ":Python:"]
|
||||
for message in messages_to_hide:
|
||||
secret = lsbset.hide("./tests/sample-files/Lenna.png", message,
|
||||
generators.eratosthenes(), 4)
|
||||
secret.save("./image.png")
|
||||
|
||||
clear_message = lsbset.reveal("./image.png",
|
||||
generators.eratosthenes(), 4)
|
||||
|
||||
self.assertEqual(message, clear_message)
|
||||
|
||||
def test_hide_and_reveal_UTF32LE(self):
|
||||
messages_to_hide = 'I love 🍕 and 🍫!'
|
||||
secret = lsbset.hide("./tests/sample-files/Lenna.png",
|
||||
messages_to_hide,
|
||||
generators.eratosthenes(),
|
||||
'UTF-32LE')
|
||||
encoding='UTF-32LE')
|
||||
secret.save("./image.png")
|
||||
|
||||
clear_message = lsbset.reveal("./image.png", generators.eratosthenes(),
|
||||
'UTF-32LE')
|
||||
encoding='UTF-32LE')
|
||||
self.assertEqual(messages_to_hide, clear_message)
|
||||
|
||||
def test_with_transparent_png(self):
|
||||
|
|
Loading…
Add table
Reference in a new issue