diff --git a/stegano/steganalysis/parity.py b/stegano/steganalysis/parity.py index 0b7d0e4..3b5607d 100644 --- a/stegano/steganalysis/parity.py +++ b/stegano/steganalysis/parity.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -#-*- coding: utf-8 -*- +# -*- coding: utf-8 -*- # Stegano - Stegano is a basic Python Steganography module. # Copyright (C) 2010-2019 Cédric Bonhomme - https://www.cedricbonhomme.org @@ -20,22 +20,23 @@ # along with this program. If not, see __author__ = "Cedric Bonhomme" -__version__ = "$Revision: 0.1 $" +__version__ = "$Revision: 0.9.4 $" __date__ = "$Date: 2010/10/01 $" +__revision__ = "$Date: 2019/06/06 $" __license__ = "GPLv3" from PIL import Image -def steganalyse(img): + +def steganalyse(img: Image.Image) -> Image.Image: """ Steganlysis of the LSB technique. """ - encoded = img.copy() + encoded = Image.new(img.mode, (img.size)) width, height = img.size - bits = "" for row in range(height): for col in range(width): - r, g, b = img.getpixel((col, row)) + r, g, b = img.getpixel((col, row))[0:3] if r % 2 == 0: r = 0 else: @@ -48,5 +49,5 @@ def steganalyse(img): b = 0 else: b = 255 - encoded.putpixel((col, row), (r, g , b)) + encoded.putpixel((col, row), (r, g, b)) return encoded diff --git a/tests/expected-results/parity.png b/tests/expected-results/parity.png new file mode 100644 index 0000000..0970ff3 Binary files /dev/null and b/tests/expected-results/parity.png differ diff --git a/tests/expected-results/parity_rgba.png b/tests/expected-results/parity_rgba.png new file mode 100644 index 0000000..a1cf2af Binary files /dev/null and b/tests/expected-results/parity_rgba.png differ diff --git a/tests/expected-results/statistics b/tests/expected-results/statistics new file mode 100644 index 0000000..028dc2e --- /dev/null +++ b/tests/expected-results/statistics @@ -0,0 +1 @@ +([58, 56, 54, 57, 60, 59, 62, 61, 63, 65, 64, 66, 67, 254, 68, 69, 255, 70, 253, 71, 72, 74, 252, 73, 251, 250, 75, 249, 76, 77], [(224, 4327), (221, 4138), (223, 4057), (222, 3987), (225, 3713), (220, 3554), (209, 3516), (207, 3476), (208, 3424), (219, 3360)]) diff --git a/tests/test_steganalysis.py b/tests/test_steganalysis.py new file mode 100644 index 0000000..8103f5d --- /dev/null +++ b/tests/test_steganalysis.py @@ -0,0 +1,74 @@ +#!/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 +# +# 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.9.4 $" +__date__ = "$Date: 2019/06/06 $" +__revision__ = "$Date: 2019/06/06 $" +__license__ = "GPLv3" + +import io +import os +import base64 +import unittest +from unittest.mock import patch + +from stegano import lsb +from stegano.steganalysis import parity, statistics +from PIL import Image, ImageChops + + +class TestSteganalysis(unittest.TestCase): + + def test_parity(self): + """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() + secret = lsb.hide("./tests/sample-files/Lenna.png", message) + analysis = parity.steganalyse(secret) + target = Image.open("./tests/expected-results/parity.png") + diff = ImageChops.difference(target, analysis).getbbox() + self.assertTrue(diff is None) + + def test_parity_rgba(self): + """ 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") + diff = ImageChops.difference(target, analysis).getbbox() + self.assertTrue(diff is None) + + def test_statistics(self): + """ Test stegano.steganalysis.statistics + """ + image = Image.open("./tests/sample-files/Lenna.png") + stats = str(statistics.steganalyse(image)) + '\n' + file = open("./tests/expected-results/statistics") + target = file.read() + file.close() + self.assertEqual(stats, target) + + +if __name__ == '__main__': + unittest.main()