mirror of
https://github.com/cedricbonhomme/Stegano.git
synced 2025-05-12 17:18:30 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
45cdb9a3a5
14 changed files with 74 additions and 40 deletions
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#-*- coding: utf-8 -*-
|
#-*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
# Stegano - Stegano is a basic Python Steganography module.
|
||||||
# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
#
|
#
|
||||||
|
@ -20,9 +20,9 @@
|
||||||
# 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.7 $"
|
__version__ = "$Revision: 0.8 $"
|
||||||
__date__ = "$Date: 2016/08/04 $"
|
__date__ = "$Date: 2016/08/04 $"
|
||||||
__revision__ = "$Date: 2017/05/16 $"
|
__revision__ = "$Date: 2019/06/01 $"
|
||||||
__license__ = "GPLv3"
|
__license__ = "GPLv3"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -58,6 +58,9 @@ group_secret.add_argument("-f", dest="secret_file",
|
||||||
parser_hide.add_argument("-o", "--output", dest="output_image_file",
|
parser_hide.add_argument("-o", "--output", dest="output_image_file",
|
||||||
required=True, help="Output image containing the secret.")
|
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
|
# Subparser: Reveal
|
||||||
parser_reveal = subparsers.add_parser('reveal', help='reveal help')
|
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.")
|
" UTF-8 (default) or UTF-32LE.")
|
||||||
parser_reveal.add_argument("-o", dest="secret_binary",
|
parser_reveal.add_argument("-o", dest="secret_binary",
|
||||||
help="Output for the binary secret (Text or any binary file).")
|
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()
|
arguments = parser.parse_args()
|
||||||
|
|
||||||
|
@ -81,7 +86,7 @@ if arguments.command == 'hide':
|
||||||
secret = tools.binary2base64(arguments.secret_file)
|
secret = tools.binary2base64(arguments.secret_file)
|
||||||
|
|
||||||
img_encoded = lsb.hide(arguments.input_image_file, secret,
|
img_encoded = lsb.hide(arguments.input_image_file, secret,
|
||||||
arguments.encoding)
|
arguments.encoding, int(arguments.shift))
|
||||||
try:
|
try:
|
||||||
img_encoded.save(arguments.output_image_file)
|
img_encoded.save(arguments.output_image_file)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -89,7 +94,8 @@ if arguments.command == 'hide':
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
elif arguments.command == 'reveal':
|
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:
|
if arguments.secret_binary != None:
|
||||||
data = tools.base642binary(secret)
|
data = tools.base642binary(secret)
|
||||||
with open(arguments.secret_binary, "wb") as f:
|
with open(arguments.secret_binary, "wb") as f:
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
# Stegano - Stegano is a basic Python Steganography module.
|
||||||
# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#-*- coding: utf-8 -*-
|
#-*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
# Stegano - Stegano is a basic Python Steganography module.
|
||||||
# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#-*- coding: utf-8 -*-
|
#-*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
# Stegano - Stegano is a basic Python Steganography module.
|
||||||
# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
|
@ -20,9 +20,9 @@
|
||||||
# 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.3 $"
|
__version__ = "$Revision: 0.4 $"
|
||||||
__date__ = "$Date: 2016/08/04 $"
|
__date__ = "$Date: 2016/08/04 $"
|
||||||
__revision__ = "$Date: 2017/05/04 $"
|
__revision__ = "$Date: 2019/06/01 $"
|
||||||
__license__ = "GPLv3"
|
__license__ = "GPLv3"
|
||||||
|
|
||||||
from typing import IO, Union
|
from typing import IO, Union
|
||||||
|
@ -34,6 +34,7 @@ def hide(
|
||||||
input_image: Union[str, IO[bytes]],
|
input_image: Union[str, IO[bytes]],
|
||||||
message: str,
|
message: str,
|
||||||
encoding: str = "UTF-8",
|
encoding: str = "UTF-8",
|
||||||
|
shift: int = 0,
|
||||||
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
|
||||||
|
@ -72,6 +73,9 @@ def hide(
|
||||||
)
|
)
|
||||||
for row in range(height):
|
for row in range(height):
|
||||||
for col in range(width):
|
for col in range(width):
|
||||||
|
if shift != 0:
|
||||||
|
shift -= 1
|
||||||
|
continue
|
||||||
if index + 3 <= len_message_bits:
|
if index + 3 <= len_message_bits:
|
||||||
|
|
||||||
# Get the colour component.
|
# Get the colour component.
|
||||||
|
@ -97,7 +101,10 @@ def hide(
|
||||||
return encoded
|
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).
|
"""Find a message in an image (with the LSB technique).
|
||||||
"""
|
"""
|
||||||
img = tools.open_image(input_image)
|
img = tools.open_image(input_image)
|
||||||
|
@ -107,7 +114,9 @@ def reveal(input_image: Union[str, IO[bytes]], encoding="UTF-8"):
|
||||||
limit = None
|
limit = None
|
||||||
for row in range(height):
|
for row in range(height):
|
||||||
for col in range(width):
|
for col in range(width):
|
||||||
|
if shift != 0:
|
||||||
|
shift -= 1
|
||||||
|
continue
|
||||||
# pixel = [r, g, b] or [r,g,b,a]
|
# pixel = [r, g, b] or [r,g,b,a]
|
||||||
pixel = img.getpixel((col, row))
|
pixel = img.getpixel((col, row))
|
||||||
if img.mode == "RGBA":
|
if img.mode == "RGBA":
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
|
@ -113,19 +113,19 @@ def ackermann_naive(m: int, n: int) -> int:
|
||||||
if m == 0:
|
if m == 0:
|
||||||
return n + 1
|
return n + 1
|
||||||
elif n == 0:
|
elif n == 0:
|
||||||
return ackermann(m - 1, 1)
|
return ackermann_naive(m - 1, 1)
|
||||||
else:
|
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.
|
"""Ackermann number.
|
||||||
"""
|
"""
|
||||||
while m >= 4:
|
while m >= 4:
|
||||||
if n == 0:
|
if n == 0:
|
||||||
n = 1
|
n = 1
|
||||||
else:
|
else:
|
||||||
n = ackermann(m, n - 1)
|
n = ackermann_fast(m, n - 1)
|
||||||
m -= 1
|
m -= 1
|
||||||
if m == 3:
|
if m == 3:
|
||||||
return (1 << n + 3) - 3
|
return (1 << n + 3) - 3
|
||||||
|
@ -136,6 +136,13 @@ def ackermann(m: int, n: int) -> int:
|
||||||
else:
|
else:
|
||||||
return n + 1
|
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]:
|
def fibonacci() -> Iterator[int]:
|
||||||
"""Generate the sequence of Fibonacci.
|
"""Generate the sequence of Fibonacci.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
|
@ -20,9 +20,9 @@
|
||||||
# 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.6 $"
|
__version__ = "$Revision: 0.7 $"
|
||||||
__date__ = "$Date: 2016/03/13 $"
|
__date__ = "$Date: 2016/03/13 $"
|
||||||
__revision__ = "$Date: 2018/12/18 $"
|
__revision__ = "$Date: 2019/05/31 $"
|
||||||
__license__ = "GPLv3"
|
__license__ = "GPLv3"
|
||||||
|
|
||||||
from typing import IO, Iterator, Union
|
from typing import IO, Iterator, Union
|
||||||
|
@ -89,14 +89,14 @@ def hide(
|
||||||
|
|
||||||
# Save the new pixel
|
# Save the new pixel
|
||||||
if img.mode == "RGBA":
|
if img.mode == "RGBA":
|
||||||
img_list[generated_number] = (r, g, b, a[0])
|
img_list[generated_number] = (r, g, b, *a)
|
||||||
else:
|
else:
|
||||||
img_list[generated_number] = (r, g, b)
|
img_list[generated_number] = (r, g, b)
|
||||||
|
|
||||||
index += 3
|
index += 3
|
||||||
|
|
||||||
# create empty new image of appropriate format
|
# 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
|
# insert saved data into the image
|
||||||
encoded.putdata(img_list)
|
encoded.putdata(img_list)
|
||||||
|
@ -126,7 +126,7 @@ def reveal(
|
||||||
while True:
|
while True:
|
||||||
generated_number = next(generator)
|
generated_number = next(generator)
|
||||||
# color = [r, g, b]
|
# 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)
|
buff += (color & 1) << (tools.ENCODINGS[encoding] - 1 - count)
|
||||||
count += 1
|
count += 1
|
||||||
if count == tools.ENCODINGS[encoding]:
|
if count == tools.ENCODINGS[encoding]:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#-*- coding: utf-8 -*-
|
#-*- 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
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#-*- coding: utf-8 -*-
|
#-*- 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
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||||
#
|
#
|
||||||
# For more information : https://github.com/cedricbonhomme/Stegano
|
# For more information : https://github.com/cedricbonhomme/Stegano
|
||||||
|
|
|
@ -91,17 +91,17 @@ class TestGenerators(unittest.TestCase):
|
||||||
"""Test the Ackermann set.
|
"""Test the Ackermann set.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.assertEqual(generators.ackermann(3, 1), 13)
|
self.assertEqual(generators.ackermann_naive(3, 1), 13)
|
||||||
self.assertEqual(generators.ackermann(3, 2), 29)
|
self.assertEqual(generators.ackermann_naive(3, 2), 29)
|
||||||
|
|
||||||
def test_ackermann(self):
|
def test_ackermann(self):
|
||||||
"""Test the Ackermann set.
|
"""Test the Ackermann set.
|
||||||
"""
|
"""
|
||||||
with open('./tests/expected-results/ackermann', 'r') as f:
|
with open('./tests/expected-results/ackermann', 'r') as f:
|
||||||
self.assertEqual(generators.ackermann(3, 1), int(f.readline()))
|
self.assertEqual(generators.ackermann_fast(3, 1), int(f.readline()))
|
||||||
self.assertEqual(generators.ackermann(3, 2), int(f.readline()))
|
self.assertEqual(generators.ackermann_fast(3, 2), int(f.readline()))
|
||||||
self.assertEqual(generators.ackermann(4, 1), int(f.readline()))
|
self.assertEqual(generators.ackermann_fast(4, 1), int(f.readline()))
|
||||||
self.assertEqual(generators.ackermann(4, 2), int(f.readline()))
|
self.assertEqual(generators.ackermann_fast(4, 2), int(f.readline()))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -54,6 +54,18 @@ class TestLSBSet(unittest.TestCase):
|
||||||
generators.eratosthenes())
|
generators.eratosthenes())
|
||||||
|
|
||||||
self.assertEqual(message, clear_message)
|
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):
|
def test_hide_and_reveal_with_shift(self):
|
||||||
messages_to_hide = ["a", "foo", "Hello World!", ":Python:"]
|
messages_to_hide = ["a", "foo", "Hello World!", ":Python:"]
|
||||||
|
|
Loading…
Add table
Reference in a new issue