diff --git a/bin/__init__.py b/bin/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/bin/__init__.py
@@ -0,0 +1 @@
+
diff --git a/bin/lsb.py b/bin/lsb.py
new file mode 100755
index 0000000..9963757
--- /dev/null
+++ b/bin/lsb.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Stegano - Stegano is a pure Python steganography module.
+# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
+#
+# For more information : https://github.com/cedricbonhomme/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.8 $"
+__date__ = "$Date: 2016/08/04 $"
+__revision__ = "$Date: 2019/06/01 $"
+__license__ = "GPLv3"
+
+import argparse
+
+try:
+ from stegano import lsb
+except:
+ print("Install Stegano: pipx install Stegano")
+
+from stegano import tools
+
+def main():
+ parser = argparse.ArgumentParser(prog='stegano-lsb')
+ subparsers = parser.add_subparsers(help='sub-command help', dest='command')
+
+ # Subparser: Hide
+ parser_hide = subparsers.add_parser('hide', help='hide help')
+ # Original image
+ parser_hide.add_argument("-i", "--input", dest="input_image_file",
+ required=True, help="Input image file.")
+ parser_hide.add_argument("-e", "--encoding", dest="encoding",
+ choices=tools.ENCODINGS.keys(), default='UTF-8',
+ help="Specify the encoding of the message to hide." +
+ " UTF-8 (default) or UTF-32LE.")
+
+ group_secret = parser_hide.add_mutually_exclusive_group(required=True)
+ # Non binary secret message to hide
+ group_secret.add_argument("-m", dest="secret_message",
+ help="Your secret message to hide (non binary).")
+ # Binary secret message to hide
+ group_secret.add_argument("-f", dest="secret_file",
+ help="Your secret to hide (Text or any binary file).")
+
+ # Image containing the secret
+ 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')
+ parser_reveal.add_argument("-i", "--input", dest="input_image_file",
+ required=True, help="Input image file.")
+ parser_reveal.add_argument("-e", "--encoding", dest="encoding",
+ choices=tools.ENCODINGS.keys(), default='UTF-8',
+ help="Specify the encoding of the message to reveal." +
+ " 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()
+
+
+ if arguments.command == 'hide':
+ if arguments.secret_message != None:
+ secret = arguments.secret_message
+ elif arguments.secret_file != None:
+ secret = tools.binary2base64(arguments.secret_file)
+
+ img_encoded = lsb.hide(arguments.input_image_file, secret,
+ arguments.encoding, int(arguments.shift))
+ try:
+ img_encoded.save(arguments.output_image_file)
+ except Exception as e:
+ # If hide() returns an error (Too long message).
+ print(e)
+
+ elif arguments.command == 'reveal':
+ 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:
+ f.write(data)
+ else:
+ print(secret)
diff --git a/bin/lsbset.py b/bin/lsbset.py
new file mode 100755
index 0000000..3f04a5f
--- /dev/null
+++ b/bin/lsbset.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Stegano - Stegano is a pure Python steganography module.
+# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
+#
+# For more information : https://github.com/cedricbonhomme/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/18 $"
+__revision__ = "$Date: 2019/06/04 $"
+__license__ = "GPLv3"
+
+import inspect
+import crayons
+
+try:
+ from stegano import lsbset
+ from stegano.lsbset import generators
+except:
+ print("Install stegano: pipx install Stegano")
+
+from stegano import tools
+
+import argparse
+
+
+
+class ValidateGenerator(argparse.Action):
+ def __call__(self, parser, args, values, option_string=None):
+ valid_generators = [generator[0] for generator in inspect.getmembers(
+ generators, inspect.isfunction)]
+ # Verify that the generator is valid
+ generator = values[0]
+ if generator not in valid_generators:
+ raise ValueError("Unknown generator: %s" % generator)
+ # Set the generator_function arg of the parser
+ setattr(args, self.dest, values)
+
+def main():
+ parser = argparse.ArgumentParser(prog='stegano-lsb-set')
+ subparsers = parser.add_subparsers(help='sub-command help', dest='command')
+
+ # Subparser: Hide
+ parser_hide = subparsers.add_parser('hide', help='hide help')
+ # Original image
+ parser_hide.add_argument("-i", "--input", dest="input_image_file",
+ required=True, help="Input image file.")
+ parser_hide.add_argument("-e", "--encoding", dest="encoding",
+ choices=tools.ENCODINGS.keys(), default='UTF-8',
+ help="Specify the encoding of the message to hide." +
+ " UTF-8 (default) or UTF-32LE.")
+
+ # Generator
+ parser_hide.add_argument("-g", "--generator", dest="generator_function",
+ action=ValidateGenerator,
+ nargs='*', required=True, help="Generator (with optional arguments)")
+ 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
+ group_secret.add_argument("-m", dest="secret_message",
+ help="Your secret message to hide (non binary).")
+ # Binary secret message to hide
+ group_secret.add_argument("-f", dest="secret_file",
+ help="Your secret to hide (Text or any binary file).")
+
+ # Image containing the secret
+ parser_hide.add_argument("-o", "--output", dest="output_image_file",
+ required=True, help="Output image containing the secret.")
+
+
+ # Subparser: Reveal
+ parser_reveal = subparsers.add_parser('reveal', help='reveal help')
+ parser_reveal.add_argument("-i", "--input", dest="input_image_file",
+ required=True, help="Input image file.")
+ parser_reveal.add_argument("-e", "--encoding", dest="encoding",
+ choices=tools.ENCODINGS.keys(), default='UTF-8',
+ help="Specify the encoding of the message to reveal." +
+ " UTF-8 (default) or UTF-32LE.")
+ parser_reveal.add_argument("-g", "--generator", dest="generator_function",
+ action=ValidateGenerator,
+ nargs='*', required=True, help="Generator (with optional arguments)")
+ 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).")
+
+
+ # Subparser: List generators
+ parser_list_generators = subparsers.add_parser('list-generators',
+ help='list-generators help')
+
+ arguments = parser.parse_args()
+
+ if arguments.command != 'list-generators':
+ try:
+ arguments.generator_function[0]
+ except AttributeError:
+ print('You must specify the name of a generator.')
+ parser.print_help()
+ exit(1)
+
+ try:
+ if (arguments.generator_function[0] == "LFSR"):
+ # Compute the size of the image for use by the LFSR generator if needed
+ tmp = tools.open_image(arguments.input_image_file)
+ size = tmp.width * tmp.height
+ tmp.close()
+ arguments.generator_function.append(size)
+ if (len(arguments.generator_function) > 1):
+ generator = getattr(generators, arguments.generator_function[0])(
+ *[int(e) for e in arguments.generator_function[1:]])
+ else:
+ generator = getattr(generators, arguments.generator_function[0])()
+
+ except AttributeError as e:
+ print("Unknown generator: {}".format(arguments.generator_function))
+ exit(1)
+
+ if arguments.command == 'hide':
+ if arguments.secret_message != None:
+ secret = arguments.secret_message
+ elif arguments.secret_file != "":
+ secret = tools.binary2base64(arguments.secret_file)
+
+ 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:
+ # If hide() returns an error (Too long message).
+ print(e)
+
+ elif arguments.command == 'reveal':
+ try:
+ secret = lsbset.reveal(arguments.input_image_file, generator,
+ int(arguments.shift))
+ except IndexError:
+ print("Impossible to detect message.")
+ exit(0)
+ if arguments.secret_binary != None:
+ data = tools.base642binary(secret)
+ with open(arguments.secret_binary, "w") as f:
+ f.write(data)
+ else:
+ print(secret)
+
+ elif arguments.command == 'list-generators':
+ all_generators = inspect.getmembers(generators, inspect.isfunction)
+ for generator in all_generators:
+ print('Generator id:')
+ print(' {}'.format(crayons.green(generator[0], bold=True)))
+ print('Desciption:')
+ print(' {}'.format(generator[1].__doc__))
diff --git a/bin/stegano-lsb-set b/bin/stegano-lsb-set
deleted file mode 100755
index faf2c30..0000000
--- a/bin/stegano-lsb-set
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Stegano - Stegano is a pure Python steganography module.
-# Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org
-#
-# For more information : https://github.com/cedricbonhomme/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/18 $"
-__revision__ = "$Date: 2019/06/04 $"
-__license__ = "GPLv3"
-
-import inspect
-import crayons
-
-try:
- from stegano import lsbset
- from stegano.lsbset import generators
-except:
- print("Install stegano: pipx install Stegano")
-
-from stegano import tools
-
-import argparse
-parser = argparse.ArgumentParser(prog='stegano-lsb-set')
-subparsers = parser.add_subparsers(help='sub-command help', dest='command')
-
-
-class ValidateGenerator(argparse.Action):
- def __call__(self, parser, args, values, option_string=None):
- valid_generators = [generator[0] for generator in inspect.getmembers(
- generators, inspect.isfunction)]
- # Verify that the generator is valid
- generator = values[0]
- if generator not in valid_generators:
- raise ValueError("Unknown generator: %s" % generator)
- # Set the generator_function arg of the parser
- setattr(args, self.dest, values)
-
-
-# Subparser: Hide
-parser_hide = subparsers.add_parser('hide', help='hide help')
-# Original image
-parser_hide.add_argument("-i", "--input", dest="input_image_file",
- required=True, help="Input image file.")
-parser_hide.add_argument("-e", "--encoding", dest="encoding",
- choices=tools.ENCODINGS.keys(), default='UTF-8',
- help="Specify the encoding of the message to hide." +
- " UTF-8 (default) or UTF-32LE.")
-
-# Generator
-parser_hide.add_argument("-g", "--generator", dest="generator_function",
- action=ValidateGenerator,
- nargs='*', required=True, help="Generator (with optional arguments)")
-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
-group_secret.add_argument("-m", dest="secret_message",
- help="Your secret message to hide (non binary).")
-# Binary secret message to hide
-group_secret.add_argument("-f", dest="secret_file",
- help="Your secret to hide (Text or any binary file).")
-
-# Image containing the secret
-parser_hide.add_argument("-o", "--output", dest="output_image_file",
- required=True, help="Output image containing the secret.")
-
-
-# Subparser: Reveal
-parser_reveal = subparsers.add_parser('reveal', help='reveal help')
-parser_reveal.add_argument("-i", "--input", dest="input_image_file",
- required=True, help="Input image file.")
-parser_reveal.add_argument("-e", "--encoding", dest="encoding",
- choices=tools.ENCODINGS.keys(), default='UTF-8',
- help="Specify the encoding of the message to reveal." +
- " UTF-8 (default) or UTF-32LE.")
-parser_reveal.add_argument("-g", "--generator", dest="generator_function",
- action=ValidateGenerator,
- nargs='*', required=True, help="Generator (with optional arguments)")
-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).")
-
-
-# Subparser: List generators
-parser_list_generators = subparsers.add_parser('list-generators',
- help='list-generators help')
-
-arguments = parser.parse_args()
-
-if arguments.command != 'list-generators':
- try:
- arguments.generator_function[0]
- except AttributeError:
- print('You must specify the name of a generator.')
- parser.print_help()
- exit(1)
-
- try:
- if (arguments.generator_function[0] == "LFSR"):
- # Compute the size of the image for use by the LFSR generator if needed
- tmp = tools.open_image(arguments.input_image_file)
- size = tmp.width * tmp.height
- tmp.close()
- arguments.generator_function.append(size)
- if (len(arguments.generator_function) > 1):
- generator = getattr(generators, arguments.generator_function[0])(
- *[int(e) for e in arguments.generator_function[1:]])
- else:
- generator = getattr(generators, arguments.generator_function[0])()
-
- except AttributeError as e:
- print("Unknown generator: {}".format(arguments.generator_function))
- exit(1)
-
-if arguments.command == 'hide':
- if arguments.secret_message != None:
- secret = arguments.secret_message
- elif arguments.secret_file != "":
- secret = tools.binary2base64(arguments.secret_file)
-
- 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:
- # If hide() returns an error (Too long message).
- print(e)
-
-elif arguments.command == 'reveal':
- try:
- secret = lsbset.reveal(arguments.input_image_file, generator,
- int(arguments.shift))
- except IndexError:
- print("Impossible to detect message.")
- exit(0)
- if arguments.secret_binary != None:
- data = tools.base642binary(secret)
- with open(arguments.secret_binary, "w") as f:
- f.write(data)
- else:
- print(secret)
-
-elif arguments.command == 'list-generators':
- all_generators = inspect.getmembers(generators, inspect.isfunction)
- for generator in all_generators:
- print('Generator id:')
- print(' {}'.format(crayons.green(generator[0], bold=True)))
- print('Desciption:')
- print(' {}'.format(generator[1].__doc__))
diff --git a/pyproject.toml b/pyproject.toml
index 8b8ad43..098902a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -30,7 +30,8 @@ include = [
]
[tool.poetry.scripts]
-stegano-lsb = "bin:steganolsb"
+stegano-lsb = "bin.lsb:main"
+stegano-lsb-set = "bin.lsbset:main"
# stegano-lsb-set = "bin.stegano-lsb-set"
# stegano-red = "bin.stegano-red"
# stegano-steganalysis-parity = "bin.stegano-steganalysis-parity"