From a1213a916380b15d8a731eedc46b9b5c2e2d4a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bonhomme?= Date: Wed, 24 Nov 2021 09:16:05 +0100 Subject: [PATCH] chg: [style] Reformated with black. --- bin/lsb.py | 104 +++++++++++++------- bin/lsbset.py | 162 ++++++++++++++++++++----------- bin/parity.py | 21 +++- bin/red.py | 32 +++--- bin/statistics.py | 8 +- docs/conf.py | 83 ++++++++-------- stegano/exifHeader/exifHeader.py | 12 ++- stegano/lsb/lsb.py | 5 +- stegano/lsbset/lsbset.py | 3 +- stegano/tools.py | 9 +- tests/test_exifHeader.py | 3 +- tests/test_lsbset.py | 8 +- tests/test_steganalysis.py | 9 +- 13 files changed, 275 insertions(+), 184 deletions(-) diff --git a/bin/lsb.py b/bin/lsb.py index f6da980..6134996 100755 --- a/bin/lsb.py +++ b/bin/lsb.py @@ -34,70 +34,104 @@ except: from stegano import tools + def main(): - parser = argparse.ArgumentParser(prog='stegano-lsb') - subparsers = parser.add_subparsers(help='sub-command help', dest='command') + 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') + 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.") + 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).") + 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).") + 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.") + 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") + 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).") + 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") + 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.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)) + 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)) + 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: diff --git a/bin/lsbset.py b/bin/lsbset.py index 046f488..ab971d4 100755 --- a/bin/lsbset.py +++ b/bin/lsbset.py @@ -39,11 +39,12 @@ 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)] + 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: @@ -51,81 +52,126 @@ class ValidateGenerator(argparse.Action): # 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') + 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') + 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.") + 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") + 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).") + 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).") + 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.") - + 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).") - + 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') + parser_list_generators = subparsers.add_parser( + "list-generators", help="list-generators help" + ) arguments = parser.parse_args() - if arguments.command != 'list-generators': + if arguments.command != "list-generators": try: arguments.generator_function[0] except AttributeError: - print('You must specify the name of a generator.') + print("You must specify the name of a generator.") parser.print_help() exit(1) try: - if (arguments.generator_function[0] == "LFSR"): + 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): + if len(arguments.generator_function) > 1: generator = getattr(generators, arguments.generator_function[0])( - *[int(e) for e in arguments.generator_function[1:]]) + *[int(e) for e in arguments.generator_function[1:]] + ) else: generator = getattr(generators, arguments.generator_function[0])() @@ -133,24 +179,26 @@ def main(): print("Unknown generator: {}".format(arguments.generator_function)) exit(1) - if arguments.command == 'hide': + 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)) + 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': + elif arguments.command == "reveal": try: - secret = lsbset.reveal(arguments.input_image_file, generator, - int(arguments.shift)) + secret = lsbset.reveal( + arguments.input_image_file, generator, int(arguments.shift) + ) except IndexError: print("Impossible to detect message.") exit(0) @@ -161,10 +209,10 @@ def main(): else: print(secret) - elif arguments.command == 'list-generators': + 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__)) + print("Generator id:") + print(" {}".format(crayons.green(generator[0], bold=True))) + print("Desciption:") + print(" {}".format(generator[1].__doc__)) diff --git a/bin/parity.py b/bin/parity.py index de24ff6..394f56c 100644 --- a/bin/parity.py +++ b/bin/parity.py @@ -33,12 +33,23 @@ try: except: print("Install Stegano: pipx install Stegano") + def main(): - parser = argparse.ArgumentParser(prog='stegano-steganalysis-parity') - parser.add_argument("-i", "--input", dest="input_image_file", - required=True, help="Input image file.") - parser.add_argument("-o", "--output", dest="output_image_file", - required=True, help="Output image file.") + parser = argparse.ArgumentParser(prog="stegano-steganalysis-parity") + parser.add_argument( + "-i", + "--input", + dest="input_image_file", + required=True, + help="Input image file.", + ) + parser.add_argument( + "-o", + "--output", + dest="output_image_file", + required=True, + help="Output image file.", + ) arguments = parser.parse_args() input_image_file = Image.open(arguments.input_image_file) diff --git a/bin/red.py b/bin/red.py index 839dc0c..2e9d956 100644 --- a/bin/red.py +++ b/bin/red.py @@ -33,27 +33,31 @@ except: def main(): - parser = argparse.ArgumentParser(prog='stegano-red') - subparsers = parser.add_subparsers(help='sub-command help', dest='command') + parser = argparse.ArgumentParser(prog="stegano-red") + subparsers = parser.add_subparsers(help="sub-command help", dest="command") - parser_hide = subparsers.add_parser('hide', help='hide help') - parser_hide.add_argument("-i", "--input", dest="input_image_file", - help="Image file") - parser_hide.add_argument("-m", dest="secret_message", - help="Your secret message to hide (non binary).") - parser_hide.add_argument("-o", "--output", dest="output_image_file", - help="Image file") + parser_hide = subparsers.add_parser("hide", help="hide help") + parser_hide.add_argument( + "-i", "--input", dest="input_image_file", help="Image file" + ) + parser_hide.add_argument( + "-m", dest="secret_message", help="Your secret message to hide (non binary)." + ) + parser_hide.add_argument( + "-o", "--output", dest="output_image_file", help="Image file" + ) - parser_reveal = subparsers.add_parser('reveal', help='reveal help') - parser_reveal.add_argument("-i", "--input", dest="input_image_file", - help="Image file") + parser_reveal = subparsers.add_parser("reveal", help="reveal help") + parser_reveal.add_argument( + "-i", "--input", dest="input_image_file", help="Image file" + ) arguments = parser.parse_args() - if arguments.command == 'hide': + if arguments.command == "hide": secret = red.hide(arguments.input_image_file, arguments.secret_message) secret.save(arguments.output_image_file) - elif arguments.command == 'reveal': + elif arguments.command == "reveal": secret = red.reveal(arguments.input_image_file) print(secret) diff --git a/bin/statistics.py b/bin/statistics.py index 735c4a5..af396fc 100644 --- a/bin/statistics.py +++ b/bin/statistics.py @@ -36,11 +36,9 @@ except: def main(): - parser = argparse.ArgumentParser(prog='stegano-steganalysis-parity') - parser.add_argument("-i", "--input", dest="input_image_file", - help="Image file") - parser.add_argument("-o", "--output", dest="output_image_file", - help="Image file") + parser = argparse.ArgumentParser(prog="stegano-steganalysis-parity") + parser.add_argument("-i", "--input", dest="input_image_file", help="Image file") + parser.add_argument("-o", "--output", dest="output_image_file", help="Image file") arguments = parser.parse_args() input_image_file = Image.open(arguments.input_image_file) diff --git a/docs/conf.py b/docs/conf.py index 335242b..84bf89f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,158 +16,157 @@ import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'Stegano' -copyright = u'2010-2021, Cédric Bonhomme' -author = 'Cédric Bonhomme ' +project = u"Stegano" +copyright = u"2010-2021, Cédric Bonhomme" +author = "Cédric Bonhomme " # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '0.9' +version = "0.9" # The full version, including alpha/beta/rc tags. -release = '0.9.4' +release = "0.9.4" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # -- Options for LaTeX output -------------------------------------------------- -latex_engine = 'pdflatex' +latex_engine = "pdflatex" # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Stgan.tex', u'Stegano Documentation', - u'Cédric Bonhomme', 'howto'), + ("index", "Stgan.tex", u"Stegano Documentation", u"Cédric Bonhomme", "howto"), ] latex_show_urls = True diff --git a/stegano/exifHeader/exifHeader.py b/stegano/exifHeader/exifHeader.py index 1b67d9d..5da6637 100644 --- a/stegano/exifHeader/exifHeader.py +++ b/stegano/exifHeader/exifHeader.py @@ -30,10 +30,13 @@ from stegano import tools def hide( - input_image_file, img_enc, secret_message=None, secret_file=None, img_format=None, + input_image_file, + img_enc, + secret_message=None, + secret_file=None, + img_format=None, ): - """Hide a message (string) in an image. - """ + """Hide a message (string) in an image.""" from zlib import compress from base64 import b64encode @@ -64,8 +67,7 @@ def hide( def reveal(input_image_file): - """Find a message in an image. - """ + """Find a message in an image.""" from base64 import b64decode from zlib import decompress diff --git a/stegano/lsb/lsb.py b/stegano/lsb/lsb.py index 4729257..c5dede8 100755 --- a/stegano/lsb/lsb.py +++ b/stegano/lsb/lsb.py @@ -98,8 +98,7 @@ def hide( 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) width, height = img.size buff, count = 0, 0 @@ -128,4 +127,4 @@ def reveal(input_image: Union[str, IO[bytes]], encoding: str = "UTF-8", shift: i if len(bitab) - len(str(limit)) - 1 == limit: img.close() - return "".join(bitab)[len(str(limit)) + 1:] + return "".join(bitab)[len(str(limit)) + 1 :] diff --git a/stegano/lsbset/lsbset.py b/stegano/lsbset/lsbset.py index 2d0230b..2bcda4a 100644 --- a/stegano/lsbset/lsbset.py +++ b/stegano/lsbset/lsbset.py @@ -106,8 +106,7 @@ def reveal( 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).""" img = tools.open_image(input_image) img_list = list(img.getdata()) width, height = img.size diff --git a/stegano/tools.py b/stegano/tools.py index a1cd923..6ddafed 100755 --- a/stegano/tools.py +++ b/stegano/tools.py @@ -67,14 +67,12 @@ def a2bits_list(chars: str, encoding: str = "UTF-8") -> List[str]: def bs(s: int) -> str: - """Converts an int to its bits representation as a string of 0's and 1's. - """ + """Converts an int to its bits representation as a string of 0's and 1's.""" return str(s) if s <= 1 else bs(s >> 1) + str(s & 1) def setlsb(component: int, bit: str) -> int: - """Set Least Significant Bit of a colour component. - """ + """Set Least Significant Bit of a colour component.""" return component & ~1 | int(bit) @@ -102,8 +100,7 @@ def binary2base64(binary_file: str) -> str: def base642binary(b64_fname: str) -> bytes: - """Convert a printable string to a binary file. - """ + """Convert a printable string to a binary file.""" b64_fname += "===" return base64.b64decode(b64_fname) diff --git a/tests/test_exifHeader.py b/tests/test_exifHeader.py index ea08842..90d0472 100644 --- a/tests/test_exifHeader.py +++ b/tests/test_exifHeader.py @@ -34,8 +34,7 @@ from stegano import exifHeader class TestEXIFHeader(unittest.TestCase): def test_hide_empty_message(self): - """Test hiding the empty string. - """ + """Test hiding the empty string.""" secret = exifHeader.hide( "./tests/sample-files/20160505T130442.jpg", "./image.jpg", secret_message="" ) diff --git a/tests/test_lsbset.py b/tests/test_lsbset.py index 6aea35c..ac96ab6 100644 --- a/tests/test_lsbset.py +++ b/tests/test_lsbset.py @@ -72,11 +72,15 @@ class TestLSBSet(unittest.TestCase): messages_to_hide = ["foo bar"] for message in messages_to_hide: secret = lsbset.hide( - "./tests/sample-files/Lenna.png", message, generators.shi_tomashi("./tests/sample-files/Lenna.png") + "./tests/sample-files/Lenna.png", + message, + generators.shi_tomashi("./tests/sample-files/Lenna.png"), ) secret.save("./image.png") - clear_message = lsbset.reveal("./image.png", generators.shi_tomashi("./tests/sample-files/Lenna.png")) + clear_message = lsbset.reveal( + "./image.png", generators.shi_tomashi("./tests/sample-files/Lenna.png") + ) self.assertEqual(message, clear_message) diff --git a/tests/test_steganalysis.py b/tests/test_steganalysis.py index 65cfdc4..87743b6 100644 --- a/tests/test_steganalysis.py +++ b/tests/test_steganalysis.py @@ -38,8 +38,7 @@ from PIL import Image, ImageChops class TestSteganalysis(unittest.TestCase): def test_parity(self): - """Test stegano.steganalysis.parity - """ + """Test stegano.steganalysis.parity""" text_file_to_hide = "./tests/sample-files/lorem_ipsum.txt" with open(text_file_to_hide) as f: message = f.read() @@ -50,8 +49,7 @@ class TestSteganalysis(unittest.TestCase): self.assertTrue(diff is None) def test_parity_rgba(self): - """ Test that stegano.steganalysis.parity works with RGBA images - """ + """Test that stegano.steganalysis.parity works with RGBA images""" img = Image.open("./tests/sample-files/transparent.png") analysis = parity.steganalyse(img) target = Image.open("./tests/expected-results/parity_rgba.png") @@ -59,8 +57,7 @@ class TestSteganalysis(unittest.TestCase): self.assertTrue(diff is None) def test_statistics(self): - """ Test stegano.steganalysis.statistics - """ + """Test stegano.steganalysis.statistics""" image = Image.open("./tests/sample-files/Lenna.png") stats = str(statistics.steganalyse(image)) + "\n" file = open("./tests/expected-results/statistics")