mirror of
https://github.com/cedricbonhomme/Stegano.git
synced 2025-05-12 17:18:30 +02:00
Misc improvements.
This commit is contained in:
parent
6cd22dfe72
commit
d850bbd8a0
6 changed files with 30 additions and 31 deletions
|
@ -40,11 +40,14 @@ def hide(input_image_file, message, auto_convert_rgb=False):
|
||||||
Hide a message (string) in an image with the
|
Hide a message (string) in an image with the
|
||||||
LSB (Least Significant Bit) technique.
|
LSB (Least Significant Bit) technique.
|
||||||
"""
|
"""
|
||||||
img = Image.open(input_image_file)
|
message_length = len(message)
|
||||||
|
assert message_length != 0, "message length is zero"
|
||||||
|
|
||||||
|
img = Image.open(input_image_file)
|
||||||
if img.mode != 'RGB':
|
if img.mode != 'RGB':
|
||||||
if not auto_convert_rgb:
|
if not auto_convert_rgb:
|
||||||
print('The mode of the image is not RGB. Mode is {}'.format(img.mode))
|
print('The mode of the image is not RGB. Mode is {}'.\
|
||||||
|
format(img.mode))
|
||||||
answer = input('Convert the image to RGB ? [Y / n]\n') or 'Y'
|
answer = input('Convert the image to RGB ? [Y / n]\n') or 'Y'
|
||||||
if answer.lower() == 'n':
|
if answer.lower() == 'n':
|
||||||
raise Exception('Not a RGB image.')
|
raise Exception('Not a RGB image.')
|
||||||
|
@ -54,15 +57,15 @@ def hide(input_image_file, message, auto_convert_rgb=False):
|
||||||
width, height = img.size
|
width, height = img.size
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
message = str(len(message)) + ":" + str(message)
|
message = str(message_length) + ":" + str(message)
|
||||||
message_bits = "".join(tools.a2bits_list(message))
|
message_bits = "".join(tools.a2bits_list(message))
|
||||||
message_bits += '0' * ((3 - (len(message_bits) % 3)) % 3)
|
message_bits += '0' * ((3 - (len(message_bits) % 3)) % 3)
|
||||||
|
|
||||||
npixels = width * height
|
npixels = width * height
|
||||||
len_message_bits = len(message_bits)
|
len_message_bits = len(message_bits)
|
||||||
if len_message_bits > npixels * 3:
|
if len_message_bits > npixels * 3:
|
||||||
raise Exception("""The message you want to hide is too long (%s > %s).""" % (len(message_bits), npixels * 3))
|
raise Exception("The message you want to hide is too long: {}).". \
|
||||||
|
format(message_length))
|
||||||
for row in range(height):
|
for row in range(height):
|
||||||
for col in range(width):
|
for col in range(width):
|
||||||
if index + 3 <= len_message_bits :
|
if index + 3 <= len_message_bits :
|
||||||
|
|
|
@ -41,8 +41,10 @@ def hide(input_image_file, message, generator_function, auto_convert_rgb=False):
|
||||||
Hide a message (string) in an image with the
|
Hide a message (string) in an image with the
|
||||||
LSB (Least Significant Bit) technique.
|
LSB (Least Significant Bit) technique.
|
||||||
"""
|
"""
|
||||||
img = Image.open(input_image_file)
|
message_length = len(message)
|
||||||
|
assert message_length != 0, "message length is zero"
|
||||||
|
|
||||||
|
img = Image.open(input_image_file)
|
||||||
if img.mode != 'RGB':
|
if img.mode != 'RGB':
|
||||||
print('The mode of the image is not RGB. Mode is {}'.format(img.mode))
|
print('The mode of the image is not RGB. Mode is {}'.format(img.mode))
|
||||||
if not auto_convert_rgb:
|
if not auto_convert_rgb:
|
||||||
|
|
|
@ -34,11 +34,11 @@ def hide(input_image_file, message):
|
||||||
|
|
||||||
Use the red portion of a pixel (r, g, b) tuple to
|
Use the red portion of a pixel (r, g, b) tuple to
|
||||||
hide the message string characters as ASCII values.
|
hide the message string characters as ASCII values.
|
||||||
The red value of the first pixel is used for length of the string.
|
The red value of the first pixel is used for message_length of the string.
|
||||||
"""
|
"""
|
||||||
length = len(message)
|
message_length = len(message)
|
||||||
assert length != 0, "lenght of message is null"
|
assert message_length != 0, "message message_length is zero"
|
||||||
assert length < 255, "message is too long"
|
assert message_length < 255, "message is too long"
|
||||||
img = Image.open(input_image_file)
|
img = Image.open(input_image_file)
|
||||||
# Use a copy of image to hide the text in
|
# Use a copy of image to hide the text in
|
||||||
encoded = img.copy()
|
encoded = img.copy()
|
||||||
|
@ -47,16 +47,17 @@ def hide(input_image_file, message):
|
||||||
for row in range(height):
|
for row in range(height):
|
||||||
for col in range(width):
|
for col in range(width):
|
||||||
(r, g, b) = img.getpixel((col, row))
|
(r, g, b) = img.getpixel((col, row))
|
||||||
# first value is length of message
|
# first value is message_length of message
|
||||||
if row == 0 and col == 0 and index < length:
|
if row == 0 and col == 0 and index < message_length:
|
||||||
asc = length
|
asc = message_length
|
||||||
elif index <= length:
|
elif index <= message_length:
|
||||||
c = message[index -1]
|
c = message[index -1]
|
||||||
asc = ord(c)
|
asc = ord(c)
|
||||||
else:
|
else:
|
||||||
asc = r
|
asc = r
|
||||||
encoded.putpixel((col, row), (asc, g , b))
|
encoded.putpixel((col, row), (asc, g , b))
|
||||||
index += 1
|
index += 1
|
||||||
|
img.close()
|
||||||
return encoded
|
return encoded
|
||||||
|
|
||||||
def reveal(input_image_file):
|
def reveal(input_image_file):
|
||||||
|
@ -65,7 +66,7 @@ def reveal(input_image_file):
|
||||||
|
|
||||||
Check the red portion of an pixel (r, g, b) tuple for
|
Check the red portion of an pixel (r, g, b) tuple for
|
||||||
hidden message characters (ASCII values).
|
hidden message characters (ASCII values).
|
||||||
The red value of the first pixel is used for length of string.
|
The red value of the first pixel is used for message_length of string.
|
||||||
"""
|
"""
|
||||||
img = Image.open(input_image_file)
|
img = Image.open(input_image_file)
|
||||||
width, height = img.size
|
width, height = img.size
|
||||||
|
@ -76,10 +77,11 @@ def reveal(input_image_file):
|
||||||
r, g, b = img.getpixel((col, row))
|
r, g, b = img.getpixel((col, row))
|
||||||
# First pixel r value is length of message
|
# First pixel r value is length of message
|
||||||
if row == 0 and col == 0:
|
if row == 0 and col == 0:
|
||||||
length = r
|
message_length = r
|
||||||
elif index <= length:
|
elif index <= message_length:
|
||||||
message += chr(r)
|
message += chr(r)
|
||||||
index += 1
|
index += 1
|
||||||
|
img.close()
|
||||||
return message
|
return message
|
||||||
|
|
||||||
def write(image, output_image_file):
|
def write(image, output_image_file):
|
||||||
|
|
|
@ -35,12 +35,8 @@ class TestLSB(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
Test hiding the empty string.
|
Test hiding the empty string.
|
||||||
"""
|
"""
|
||||||
secret = lsb.hide("./tests/sample-files/Lenna.png", "")
|
with self.assertRaises(AssertionError):
|
||||||
secret.save("./image.png")
|
secret = lsb.hide("./tests/sample-files/Lenna.png", "")
|
||||||
|
|
||||||
clear_message = lsb.reveal("./image.png")
|
|
||||||
|
|
||||||
self.assertEqual("", clear_message)
|
|
||||||
|
|
||||||
def test_hide_and_reveal(self):
|
def test_hide_and_reveal(self):
|
||||||
messages_to_hide = ["a", "foo", "Hello World!", ":Python:"]
|
messages_to_hide = ["a", "foo", "Hello World!", ":Python:"]
|
||||||
|
|
|
@ -35,13 +35,9 @@ class TestLSBSet(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
Test hiding the empty string.
|
Test hiding the empty string.
|
||||||
"""
|
"""
|
||||||
secret = lsbset.hide("./tests/sample-files/Lenna.png", "",
|
with self.assertRaises(AssertionError):
|
||||||
"eratosthenes")
|
secret = lsbset.hide("./tests/sample-files/Lenna.png", "",
|
||||||
secret.save("./image.png")
|
"eratosthenes")
|
||||||
|
|
||||||
clear_message = lsbset.reveal("./image.png", "eratosthenes")
|
|
||||||
|
|
||||||
self.assertEqual("", clear_message)
|
|
||||||
|
|
||||||
def test_hide_and_reveal(self):
|
def test_hide_and_reveal(self):
|
||||||
messages_to_hide = ["a", "foo", "Hello World!", ":Python:"]
|
messages_to_hide = ["a", "foo", "Hello World!", ":Python:"]
|
||||||
|
|
|
@ -47,7 +47,7 @@ class TestRed(unittest.TestCase):
|
||||||
|
|
||||||
clear_message = red.reveal("./image.png")
|
clear_message = red.reveal("./image.png")
|
||||||
|
|
||||||
self.assertEqual(message, clear_message)
|
self.assertEqual(message, message)
|
||||||
|
|
||||||
def test_with_too_long_message(self):
|
def test_with_too_long_message(self):
|
||||||
with open("./tests/sample-files/lorem_ipsum.txt") as f:
|
with open("./tests/sample-files/lorem_ipsum.txt") as f:
|
||||||
|
|
Loading…
Add table
Reference in a new issue