diff --git a/bin/stegano-lsb b/bin/stegano-lsb
index 5fa4681..b49fd11 100755
--- a/bin/stegano-lsb
+++ b/bin/stegano-lsb
@@ -1,8 +1,8 @@
#!/usr/bin/env python
#-*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
-# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
+# Stegano - Stegano is a basic Python Steganography module.
+# Copyright (C) 2010-2019 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
__author__ = "Cedric Bonhomme"
-__version__ = "$Revision: 0.7 $"
+__version__ = "$Revision: 0.8 $"
__date__ = "$Date: 2016/08/04 $"
-__revision__ = "$Date: 2017/05/16 $"
+__revision__ = "$Date: 2019/06/01 $"
__license__ = "GPLv3"
try:
@@ -58,6 +58,9 @@ group_secret.add_argument("-f", dest="secret_file",
parser_hide.add_argument("-o", "--output", dest="output_image_file",
required=True, help="Output image containing the secret.")
+# Shift the message to hide
+parser_hide.add_argument("-s", "--shift", dest="shift", default=0,
+ help="Shift for the message to hide")
# Subparser: Reveal
parser_reveal = subparsers.add_parser('reveal', help='reveal help')
@@ -69,7 +72,9 @@ parser_reveal.add_argument("-e", "--encoding", dest="encoding",
" UTF-8 (default) or UTF-32LE.")
parser_reveal.add_argument("-o", dest="secret_binary",
help="Output for the binary secret (Text or any binary file).")
-
+# Shift the message to reveal
+parser_reveal.add_argument("-s", "--shift", dest="shift", default=0,
+ help="Shift for the reveal")
arguments = parser.parse_args()
@@ -81,7 +86,7 @@ if arguments.command == 'hide':
secret = tools.binary2base64(arguments.secret_file)
img_encoded = lsb.hide(arguments.input_image_file, secret,
- arguments.encoding)
+ arguments.encoding, int(arguments.shift))
try:
img_encoded.save(arguments.output_image_file)
except Exception as e:
@@ -89,7 +94,8 @@ if arguments.command == 'hide':
print(e)
elif arguments.command == 'reveal':
- secret = lsb.reveal(arguments.input_image_file, arguments.encoding)
+ secret = lsb.reveal(arguments.input_image_file, arguments.encoding,
+ int(arguments.shift))
if arguments.secret_binary != None:
data = tools.base642binary(secret)
with open(arguments.secret_binary, "wb") as f:
diff --git a/bin/stegano-red b/bin/stegano-red
index ef36caf..5798f55 100644
--- a/bin/stegano-red
+++ b/bin/stegano-red
@@ -1,8 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
-# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
+# Stegano - Stegano is a basic Python Steganography module.
+# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
#
diff --git a/bin/stegano-steganalysis-parity b/bin/stegano-steganalysis-parity
index 4d54586..32e4ef3 100644
--- a/bin/stegano-steganalysis-parity
+++ b/bin/stegano-steganalysis-parity
@@ -1,8 +1,8 @@
#!/usr/bin/env python
#-*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
-# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
+# Stegano - Stegano is a basic Python Steganography module.
+# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
#
diff --git a/bin/stegano-steganalysis-statistics b/bin/stegano-steganalysis-statistics
index 1cbe28b..a368c03 100644
--- a/bin/stegano-steganalysis-statistics
+++ b/bin/stegano-steganalysis-statistics
@@ -1,8 +1,8 @@
#!/usr/bin/env python
#-*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
-# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
+# Stegano - Stegano is a basic Python Steganography module.
+# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
#
diff --git a/stegano/exifHeader/exifHeader.py b/stegano/exifHeader/exifHeader.py
index 9a15ce2..e16f5ff 100644
--- a/stegano/exifHeader/exifHeader.py
+++ b/stegano/exifHeader/exifHeader.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
+# Stegano - Stegano is a basic Python Steganography module.
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
diff --git a/stegano/lsb/lsb.py b/stegano/lsb/lsb.py
index 8c0ac87..9ea1095 100755
--- a/stegano/lsb/lsb.py
+++ b/stegano/lsb/lsb.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
+# Stegano - Stegano is a basic Python Steganography module.
# Copyright (C) 2010-2019 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
__author__ = "Cedric Bonhomme"
-__version__ = "$Revision: 0.3 $"
+__version__ = "$Revision: 0.4 $"
__date__ = "$Date: 2016/08/04 $"
-__revision__ = "$Date: 2017/05/04 $"
+__revision__ = "$Date: 2019/06/01 $"
__license__ = "GPLv3"
from typing import IO, Union
@@ -34,6 +34,7 @@ def hide(
input_image: Union[str, IO[bytes]],
message: str,
encoding: str = "UTF-8",
+ shift: int = 0,
auto_convert_rgb: bool = False,
):
"""Hide a message (string) in an image with the
@@ -72,6 +73,9 @@ def hide(
)
for row in range(height):
for col in range(width):
+ if shift != 0:
+ shift -= 1
+ continue
if index + 3 <= len_message_bits:
# Get the colour component.
@@ -97,7 +101,10 @@ def hide(
return encoded
-def reveal(input_image: Union[str, IO[bytes]], encoding="UTF-8"):
+def reveal(input_image: Union[str, IO[bytes]],
+ encoding: str = "UTF-8",
+ shift: int = 0
+):
"""Find a message in an image (with the LSB technique).
"""
img = tools.open_image(input_image)
@@ -107,7 +114,9 @@ def reveal(input_image: Union[str, IO[bytes]], encoding="UTF-8"):
limit = None
for row in range(height):
for col in range(width):
-
+ if shift != 0:
+ shift -= 1
+ continue
# pixel = [r, g, b] or [r,g,b,a]
pixel = img.getpixel((col, row))
if img.mode == "RGBA":
diff --git a/stegano/lsbset/generators.py b/stegano/lsbset/generators.py
index f0bdee9..5db3a7f 100644
--- a/stegano/lsbset/generators.py
+++ b/stegano/lsbset/generators.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
+# Stegano - Stegano is a basic Python Steganography module.
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
@@ -113,19 +113,19 @@ def ackermann_naive(m: int, n: int) -> int:
if m == 0:
return n + 1
elif n == 0:
- return ackermann(m - 1, 1)
+ return ackermann_naive(m - 1, 1)
else:
- return ackermann(m - 1, ackermann(m, n - 1))
+ return ackermann_naive(m - 1, ackermann_naive(m, n - 1))
-def ackermann(m: int, n: int) -> int:
+def ackermann_fast(m: int, n: int) -> int:
"""Ackermann number.
"""
while m >= 4:
if n == 0:
n = 1
else:
- n = ackermann(m, n - 1)
+ n = ackermann_fast(m, n - 1)
m -= 1
if m == 3:
return (1 << n + 3) - 3
@@ -136,6 +136,13 @@ def ackermann(m: int, n: int) -> int:
else:
return n + 1
+def ackermann(m: int) -> Iterator[int]:
+ """Ackermann encapsulated in a generator.
+ """
+ n = 0
+ while True:
+ yield ackermann_fast(m, n)
+ n += 1
def fibonacci() -> Iterator[int]:
"""Generate the sequence of Fibonacci.
diff --git a/stegano/lsbset/lsbset.py b/stegano/lsbset/lsbset.py
index 04fa9fa..5e0c22a 100644
--- a/stegano/lsbset/lsbset.py
+++ b/stegano/lsbset/lsbset.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
+# Stegano - Stegano is a basic Python Steganography module.
# Copyright (C) 2010-2019 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
__author__ = "Cedric Bonhomme"
-__version__ = "$Revision: 0.6 $"
+__version__ = "$Revision: 0.7 $"
__date__ = "$Date: 2016/03/13 $"
-__revision__ = "$Date: 2018/12/18 $"
+__revision__ = "$Date: 2019/05/31 $"
__license__ = "GPLv3"
from typing import IO, Iterator, Union
@@ -89,14 +89,14 @@ def hide(
# Save the new pixel
if img.mode == "RGBA":
- img_list[generated_number] = (r, g, b, a[0])
+ img_list[generated_number] = (r, g, b, *a)
else:
img_list[generated_number] = (r, g, b)
index += 3
# create empty new image of appropriate format
- encoded = Image.new("RGB", (img.size))
+ encoded = Image.new(img.mode, (img.size))
# insert saved data into the image
encoded.putdata(img_list)
@@ -126,7 +126,7 @@ def reveal(
while True:
generated_number = next(generator)
# color = [r, g, b]
- for color in img_list[generated_number]:
+ for color in img_list[generated_number][:3]: # ignore the alpha
buff += (color & 1) << (tools.ENCODINGS[encoding] - 1 - count)
count += 1
if count == tools.ENCODINGS[encoding]:
diff --git a/stegano/red/red.py b/stegano/red/red.py
index ff841b5..a17bc52 100755
--- a/stegano/red/red.py
+++ b/stegano/red/red.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
+# Stegano - Stéganô is a basic Python Steganography module.
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
diff --git a/stegano/steganalysis/parity.py b/stegano/steganalysis/parity.py
index e0e76c6..0b7d0e4 100644
--- a/stegano/steganalysis/parity.py
+++ b/stegano/steganalysis/parity.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#-*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
+# Stegano - Stegano is a basic Python Steganography module.
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
diff --git a/stegano/steganalysis/statistics.py b/stegano/steganalysis/statistics.py
index 45794a6..d85248b 100644
--- a/stegano/steganalysis/statistics.py
+++ b/stegano/steganalysis/statistics.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#-*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
+# Stegano - Stegano is a basic Python Steganography module.
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
diff --git a/stegano/tools.py b/stegano/tools.py
index 897bba4..9870000 100755
--- a/stegano/tools.py
+++ b/stegano/tools.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Stéganô - Stéganô is a basic Python Steganography module.
+# Stegano - Stéganô is a basic Python Steganography module.
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
#
# For more information : https://github.com/cedricbonhomme/Stegano
diff --git a/tests/test_generators.py b/tests/test_generators.py
index 2d64ec1..58d9df3 100644
--- a/tests/test_generators.py
+++ b/tests/test_generators.py
@@ -91,17 +91,17 @@ class TestGenerators(unittest.TestCase):
"""Test the Ackermann set.
"""
- self.assertEqual(generators.ackermann(3, 1), 13)
- self.assertEqual(generators.ackermann(3, 2), 29)
+ self.assertEqual(generators.ackermann_naive(3, 1), 13)
+ self.assertEqual(generators.ackermann_naive(3, 2), 29)
def test_ackermann(self):
"""Test the Ackermann set.
"""
with open('./tests/expected-results/ackermann', 'r') as f:
- self.assertEqual(generators.ackermann(3, 1), int(f.readline()))
- self.assertEqual(generators.ackermann(3, 2), int(f.readline()))
- self.assertEqual(generators.ackermann(4, 1), int(f.readline()))
- self.assertEqual(generators.ackermann(4, 2), int(f.readline()))
+ self.assertEqual(generators.ackermann_fast(3, 1), int(f.readline()))
+ self.assertEqual(generators.ackermann_fast(3, 2), int(f.readline()))
+ self.assertEqual(generators.ackermann_fast(4, 1), int(f.readline()))
+ self.assertEqual(generators.ackermann_fast(4, 2), int(f.readline()))
if __name__ == '__main__':
unittest.main()
diff --git a/tests/test_lsbset.py b/tests/test_lsbset.py
index 82fe754..548cac8 100644
--- a/tests/test_lsbset.py
+++ b/tests/test_lsbset.py
@@ -54,6 +54,18 @@ class TestLSBSet(unittest.TestCase):
generators.eratosthenes())
self.assertEqual(message, clear_message)
+
+ def test_hide_and_reveal_with_ackermann(self):
+ messages_to_hide = ["foo"]
+ for message in messages_to_hide:
+ secret = lsbset.hide("./tests/sample-files/Lenna.png", message,
+ generators.ackermann(m=3))
+ secret.save("./image.png")
+
+ clear_message = lsbset.reveal("./image.png",
+ generators.ackermann(m=3))
+
+ self.assertEqual(message, clear_message)
def test_hide_and_reveal_with_shift(self):
messages_to_hide = ["a", "foo", "Hello World!", ":Python:"]