forked from x4nth055/pythoncode-tutorials
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
110 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# [How to use Steganography to Hide Secret Data in Images in Python](https://www.thepythoncode.com/article/hide-secret-data-in-images-using-steganography-python) | ||
To run this: | ||
- `pip3 install -r requimements.txt` | ||
- To encode some data to the imag `image.PNG` and decode it right away: | ||
``` | ||
python steganography image.PNG "This is some secret data." | ||
``` | ||
This will write another image with data encoded in it and **outputs:** | ||
``` | ||
[*] Maximum bytes to encode: 125028 | ||
[*] Encoding data... | ||
[+] Decoding... | ||
[+] Decoded data: This is some secret data. | ||
``` | ||
- You can isolate encoding and decoding processes in two different Python files, which makes more sense. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
opencv-python | ||
numpy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import cv2 | ||
import numpy as np | ||
import sys | ||
|
||
|
||
def to_bin(data): | ||
"""Convert `data` to binary format as string""" | ||
if isinstance(data, str): | ||
return ''.join([ format(ord(i), "08b") for i in data ]) | ||
elif isinstance(data, bytes) or isinstance(data, np.ndarray): | ||
return [ format(i, "08b") for i in data ] | ||
elif isinstance(data, int) or isinstance(data, np.uint8): | ||
return format(data, "08b") | ||
else: | ||
raise TypeError("Type not supported.") | ||
|
||
|
||
def encode(image_name, secret_data): | ||
# read the image | ||
image = cv2.imread(image_name) | ||
# maximum bytes to encode | ||
n_bytes = image.shape[0] * image.shape[1] * 3 // 8 | ||
print("[*] Maximum bytes to encode:", n_bytes) | ||
if len(secret_data) > n_bytes: | ||
raise ValueError("[!] Insufficient bytes, need bigger image or less data.") | ||
print("[*] Encoding data...") | ||
# add stopping criteria | ||
secret_data += "=====" | ||
data_index = 0 | ||
# convert data to binary | ||
binary_secret_data = to_bin(secret_data) | ||
# size of data to hide | ||
data_len = len(binary_secret_data) | ||
|
||
for row in image: | ||
for pixel in row: | ||
# convert RGB values to binary format | ||
r, g, b = to_bin(pixel) | ||
# modify the least significant bit only if there is still data to store | ||
if data_index < data_len: | ||
# least significant red pixel bit | ||
pixel[0] = int(r[:-1] + binary_secret_data[data_index], 2) | ||
data_index += 1 | ||
if data_index < data_len: | ||
# least significant green pixel bit | ||
pixel[1] = int(g[:-1] + binary_secret_data[data_index], 2) | ||
data_index += 1 | ||
if data_index < data_len: | ||
# least significant blue pixel bit | ||
pixel[2] = int(b[:-1] + binary_secret_data[data_index], 2) | ||
data_index += 1 | ||
# if data is encoded, just break out of the loop | ||
if data_index >= data_len: | ||
break | ||
return image | ||
|
||
|
||
def decode(image_name): | ||
print("[+] Decoding...") | ||
# read the image | ||
image = cv2.imread(image_name) | ||
binary_data = "" | ||
for row in image: | ||
for pixel in row: | ||
r, g, b = to_bin(pixel) | ||
binary_data += r[-1] | ||
binary_data += g[-1] | ||
binary_data += b[-1] | ||
|
||
# split by 8-bits | ||
all_bytes = [ binary_data[i: i+8] for i in range(0, len(binary_data), 8) ] | ||
# convert from bits to characters | ||
decoded_data = "" | ||
for byte in all_bytes: | ||
decoded_data += chr(int(byte, 2)) | ||
if decoded_data[-5:] == "=====": | ||
break | ||
return decoded_data[:-5] | ||
|
||
|
||
if __name__ == "__main__": | ||
input_image = sys.argv[1] | ||
output_image = f"encoded_{input_image}" | ||
secret_data = sys.argv[2] | ||
|
||
# encode the data into the image | ||
encoded_image = encode(image_name=input_image, secret_data=secret_data) | ||
# save the output image (encoded image) | ||
cv2.imwrite(output_image, encoded_image) | ||
# decode the secret data from the image | ||
decoded_data = decode(output_image) | ||
print("[+] Decoded data:", decoded_data) |