mirror of
https://github.com/cedricbonhomme/Stegano.git
synced 2025-05-12 17:18:30 +02:00
Merge pull request #26 from AdrienCos/master
Implemented Ackemann generators CLI interface
This commit is contained in:
commit
bf094c0361
3 changed files with 106 additions and 53 deletions
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
#-*- coding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
||||
# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||
|
@ -22,7 +22,7 @@
|
|||
__author__ = "Cedric Bonhomme"
|
||||
__version__ = "$Revision: 0.7 $"
|
||||
__date__ = "$Date: 2016/03/18 $"
|
||||
__revision__ = "$Date: 2017/05/16 $"
|
||||
__revision__ = "$Date: 2019/06/04 $"
|
||||
__license__ = "GPLv3"
|
||||
|
||||
import inspect
|
||||
|
@ -40,6 +40,19 @@ 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
|
||||
|
@ -52,9 +65,8 @@ parser_hide.add_argument("-e", "--encoding", dest="encoding",
|
|||
|
||||
# Generator
|
||||
parser_hide.add_argument("-g", "--generator", dest="generator_function",
|
||||
choices=[generator[0] for generator in \
|
||||
inspect.getmembers(generators, inspect.isfunction)],
|
||||
required=True, help="Generator")
|
||||
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")
|
||||
|
||||
|
@ -80,9 +92,8 @@ parser_reveal.add_argument("-e", "--encoding", dest="encoding",
|
|||
help="Specify the encoding of the message to reveal." +
|
||||
" UTF-8 (default) or UTF-32LE.")
|
||||
parser_reveal.add_argument("-g", "--generator", dest="generator_function",
|
||||
choices=[generator[0] for generator in \
|
||||
inspect.getmembers(generators, inspect.isfunction)],
|
||||
required=True, help="Generator")
|
||||
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",
|
||||
|
@ -97,14 +108,19 @@ arguments = parser.parse_args()
|
|||
|
||||
if arguments.command != 'list-generators':
|
||||
try:
|
||||
arguments.generator_function
|
||||
arguments.generator_function[0]
|
||||
except AttributeError:
|
||||
print('You must specify the name of a generator.')
|
||||
parser.print_help()
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
generator = getattr(generators, arguments.generator_function)()
|
||||
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)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
__author__ = "Cedric Bonhomme"
|
||||
__version__ = "$Revision: 0.3 $"
|
||||
__date__ = "$Date: 2011/12/28 $"
|
||||
__revision__ = "$Date: 2017/03/10 $"
|
||||
__revision__ = "$Date: 2019/06/04 $"
|
||||
__license__ = "GPLv3"
|
||||
|
||||
import itertools
|
||||
|
@ -107,15 +107,24 @@ def carmichael() -> Iterator[int]:
|
|||
yield m
|
||||
|
||||
|
||||
def ackermann_naive(m: int, n: int) -> int:
|
||||
def ackermann_slow(m: int, n: int) -> int:
|
||||
"""Ackermann number.
|
||||
"""
|
||||
if m == 0:
|
||||
return n + 1
|
||||
elif n == 0:
|
||||
return ackermann_naive(m - 1, 1)
|
||||
return ackermann_slow(m - 1, 1)
|
||||
else:
|
||||
return ackermann_naive(m - 1, ackermann_naive(m, n - 1))
|
||||
return ackermann_slow(m - 1, ackermann_slow(m, n - 1))
|
||||
|
||||
|
||||
def ackermann_naive(m: int) -> Iterator[int]:
|
||||
"""Naive Ackermann encapsulated in a generator
|
||||
"""
|
||||
n = 0
|
||||
while True:
|
||||
yield ackermann_slow(m, n)
|
||||
n += 1
|
||||
|
||||
|
||||
def ackermann_fast(m: int, n: int) -> int:
|
||||
|
@ -136,6 +145,7 @@ def ackermann_fast(m: int, n: int) -> int:
|
|||
else:
|
||||
return n + 1
|
||||
|
||||
|
||||
def ackermann(m: int) -> Iterator[int]:
|
||||
"""Ackermann encapsulated in a generator.
|
||||
"""
|
||||
|
@ -144,6 +154,7 @@ def ackermann(m: int) -> Iterator[int]:
|
|||
yield ackermann_fast(m, n)
|
||||
n += 1
|
||||
|
||||
|
||||
def fibonacci() -> Iterator[int]:
|
||||
"""Generate the sequence of Fibonacci.
|
||||
https://oeis.org/A000045
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
#-*- coding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Stéganô - Stéganô is a basic Python Steganography module.
|
||||
# Copyright (C) 2010-2017 Cédric Bonhomme - https://www.cedricbonhomme.org
|
||||
|
@ -30,6 +30,7 @@ import itertools
|
|||
|
||||
from stegano.lsbset import generators
|
||||
|
||||
|
||||
class TestGenerators(unittest.TestCase):
|
||||
|
||||
def test_identity(self):
|
||||
|
@ -87,21 +88,46 @@ class TestGenerators(unittest.TestCase):
|
|||
self.assertEqual(tuple(itertools.islice(generators.carmichael(), 33)),
|
||||
tuple(int(line) for line in f))
|
||||
|
||||
def test_ackermann_naive(self):
|
||||
"""Test the Ackermann set.
|
||||
"""
|
||||
|
||||
self.assertEqual(generators.ackermann_naive(3, 1), 13)
|
||||
self.assertEqual(generators.ackermann_naive(3, 2), 29)
|
||||
|
||||
def test_ackermann(self):
|
||||
def test_ackermann_slow(self):
|
||||
"""Test the Ackermann set.
|
||||
"""
|
||||
with open('./tests/expected-results/ackermann', 'r') as f:
|
||||
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()))
|
||||
self.assertEqual(generators.ackermann_slow(
|
||||
3, 1), int(f.readline()))
|
||||
self.assertEqual(generators.ackermann_slow(
|
||||
3, 2), int(f.readline()))
|
||||
|
||||
def test_ackermann_naive(self):
|
||||
"""Test the Naive Ackermann generator
|
||||
"""
|
||||
gen = generators.ackermann_naive(3)
|
||||
next(gen)
|
||||
with open('./tests/expected-results/ackermann', 'r') as f:
|
||||
self.assertEqual(next(gen), int(f.readline()))
|
||||
self.assertEqual(next(gen), int(f.readline()))
|
||||
|
||||
def test_ackermann_fast(self):
|
||||
"""Test the Ackermann set.
|
||||
"""
|
||||
with open('./tests/expected-results/ackermann', 'r') as f:
|
||||
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()))
|
||||
|
||||
def test_ackermann(self):
|
||||
"""Test the Ackermann generator
|
||||
"""
|
||||
gen = generators.ackermann(3)
|
||||
next(gen)
|
||||
with open('./tests/expected-results/ackermann', 'r') as f:
|
||||
self.assertEqual(next(gen), int(f.readline()))
|
||||
self.assertEqual(next(gen), int(f.readline()))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Add table
Reference in a new issue