Skip to content

Commit 57f81cd

Browse files
committed
adding comments and readme
1 parent bd1bc0b commit 57f81cd

File tree

10 files changed

+102
-4
lines changed

10 files changed

+102
-4
lines changed

Python/Image-Steganography/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Image Steganography
2+
Steganography is the art and science of embedding secret messages in a cover message or file in such a way that no one, apart from the sender and the intended recipient, suspects the existence of the message. In case of Image Steganography, secret messages are embedded in images.
3+
4+
![flowchart](https://d1jnx9ba8s6j9r.cloudfront.net/blog/wp-content/uploads/2019/01/SteganogarphyModel-528x259.png)
5+
6+
One of the algorithms to do so is known as **Least Significant Bit Insertion**. In this script the following operations are done:
7+
8+
**While Hiding:**
9+
1. Image and message is read from a text file.
10+
2. The message is encrypted with a key.
11+
3. The encrypted message is then embedded with the image.
12+
13+
**While Retrieving:**
14+
1. Encrypted message is extracted from the image.
15+
2. Exncrypted message is then decrypted using the previous key.
16+
17+
## Executing the script:
18+
* First install dependencies using: `pip install -r requirements.txt`
19+
* To hide run: `python hide.py <image_path> <message_file_path>`
20+
* for e.g: `python hide.py sample.png info.txt`
21+
* To retrieve run: `python retrieve.py <image_path> <key_path>`
22+
* for e.g: `python retrieve.py sample_secret.png key`
23+
24+
> Note: Avoid using JPEG or JPG files as they ruin the integrity of the message due to compression.
25+
26+
27+
## Output:
28+
29+
**sample.png:**
30+
31+
![sample source](images/sample.png)
32+
33+
**info.txt:**
34+
35+
```txt
36+
Hello, this file's content will be hidden.
37+
```
38+
39+
**Hiding:**
40+
41+
![hiding](images/hiding.png)
42+
43+
44+
**sample_secret.png**
45+
46+
![sample secret](images/sample_secret.png)
47+
48+
The image with the hidden message.
49+
50+
51+
**key:**
52+
53+
`hrnyzqoF3aOwaOO4n9vnunH9KUD-nh-Ee5fjQcuLU9k=`
54+
55+
**Retrieving:**
56+
57+
![retrieving](images/retrieving.png)
58+
59+
Thank You!

Python/Image-Steganography/hide.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
import sys
44
from cryptography.fernet import Fernet
55

6-
6+
# Check if the user has entered commandline arguments correctly or not.
77
if len(sys.argv) < 3:
88
print("Provide appropriate commandline arguments.")
99
sys.exit()
1010

1111

12+
# Method to convert various data to binary.
1213
def message_to_binary(message):
1314
if type(message) == str:
1415
return ''.join([ format(ord(i), "08b") for i in message ])
@@ -20,63 +21,83 @@ def message_to_binary(message):
2021
raise TypeError("Input type not supported")
2122

2223

24+
# Method to generate key and encrypt secrect message.
2325
def encrypt_message(message):
2426
key = Fernet.generate_key()
2527
encrypted_message = Fernet(key).encrypt(message.encode())
2628

2729
return encrypted_message, key
2830

2931

32+
# Method to embed encrypted message within the image.
3033
def hide_info(image, message):
3134

35+
# Encrypt the message.
3236
enc_message, key = encrypt_message(message)
3337
enc_message = enc_message.decode()
3438

39+
# Get the maximum amount of byte data that can be embeded within the image.
3540
max_bytes = image.shape[0] * image.shape[1] * 3//8
3641

42+
# Check if the data is within limits.
3743
if len(enc_message) > max_bytes:
3844
raise ValueError("Insufficient bytes, provide bigger image or shorter message.")
3945

46+
# Add salt delimiter.
4047
enc_message += "#####"
4148

4249
data_index = 0
4350
bin_enc_message = message_to_binary(enc_message)
4451

4552
data_len = len(bin_enc_message)
4653

54+
# Initiate embedding process.
4755
for values in image:
4856
for pixel in values:
57+
# Convert pixel data to binary.
4958
r, g, b = message_to_binary(pixel)
5059

60+
# modify the least significant bit remaining data is available.
5161
if data_index < data_len:
62+
# Hide data into LSB of red pixel
5263
pixel[0] = int(r[:-1] + bin_enc_message[data_index], 2)
5364
data_index += 1
5465

5566
if data_index < data_len:
67+
# Hide data into LSB of green pixel
5668
pixel[1] = int(g[:-1] + bin_enc_message[data_index], 2)
5769
data_index += 1
5870

5971
if data_index < data_len:
72+
# Hide data into LSB of blue pixel
6073
pixel[2] = int(b[:-1] + bin_enc_message[data_index], 2)
6174
data_index += 1
6275

76+
# Break out of the loop if there isn't any data left to embed.
6377
if data_index >= data_len:
6478
break
6579

80+
# Save the encryption key in a file.
6681
with open("key", "wb") as f:
6782
f.write(key)
6883

6984
return image
7085

7186

87+
# Extract image and message path.
7288
image_path = sys.argv[1]
7389
message_path = sys.argv[2]
7490

91+
92+
# Load image and message to memory.
7593
source_image = cv2.imread(image_path)
7694
with open(message_path, "r") as f:
7795
message = f.read()
7896

97+
98+
# Perform the embeded operation and save the resultant image.
7999
secret_image = hide_info(source_image, message)
80100
secret_image_path = image_path.split(".")
81101
secret_image_path = secret_image_path[-2]+"_secret."+secret_image_path[-1]
82102
cv2.imwrite(secret_image_path, secret_image)
103+
print("Message successfully hidden.")
8.74 KB
Loading
10.5 KB
Loading
Loading

Python/Image-Steganography/key

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
UJRsXUb0QISvEQwbyl4M0FVhl-Xt1X_mWyjQClbT3KE=
1+
hrnyzqoF3aOwaOO4n9vnunH9KUD-nh-Ee5fjQcuLU9k=
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
opencv-python
2+
cryptography

Python/Image-Steganography/retrieve.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import numpy as np
44
import sys
55

6+
7+
# Check if user has provided commandline arguments or not.
68
if len(sys.argv) < 3:
79
print("Provide appropriate commandline arguments.")
810
sys.exit()
911

1012

13+
# Convert various data to binary.
1114
def message_to_binary(message):
1215
if type(message) == str:
1316
return ''.join([ format(ord(i), "08b") for i in message ])
@@ -19,39 +22,52 @@ def message_to_binary(message):
1922
raise TypeError("Input type not supported")
2023

2124

25+
# Decrypt an encrypted message.
2226
def decrypt_message(enc_message, key):
2327
dec_message = Fernet(key).decrypt(enc_message)
2428
return dec_message
2529

2630

31+
# Retrive the message from an image.
2732
def retrieve_info(image, key):
2833

2934
binary_data = ""
3035

3136
for values in image:
3237
for pixel in values:
38+
# Convert pixel to binary.
3339
r, g, b = message_to_binary(pixel)
40+
41+
# Extracting data from the LSB of all the channels.
3442
binary_data += r[-1]
3543
binary_data += g[-1]
3644
binary_data += b[-1]
3745

46+
# split by 8 bits.
3847
all_bytes = [binary_data[i: i+8] for i in range(0, len(binary_data), 8)]
3948

49+
# Convert to ASCII values.
4050
decoded_data = ""
4151
for byte in all_bytes:
4252
decoded_data += chr(int(byte, 2))
4353
if decoded_data[-5:] == "#####":
4454
break
4555

46-
message = decrypt_message(decoded_data[:-5].encode(), key)
56+
# Decrypt the encryption.
57+
message = decrypt_message(decoded_data[:-5].encode(), key).decode()
4758

48-
return message.decode()
59+
return message
4960

61+
62+
# Extract the image and key path.
5063
image_path = sys.argv[1]
5164
key_path = sys.argv[2]
5265

66+
67+
# Read the image and key.
5368
steg_image = cv2.imread(image_path)
5469
with open(key_path, "rb") as f:
5570
key = f.read()
5671

72+
# Display the secrect message.
5773
print(f"Secret Message:{retrieve_info(steg_image, key)}")
-83.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)