Created
May 3, 2024 07:50
-
-
Save yvki/da4ad872541374e969437a5f3f253683 to your computer and use it in GitHub Desktop.
LSB Replacement method ποΈ in Python for Steganography
This file contains hidden or 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
# Import required computer vision and array-based math libraries | |
import cv2, numpy as np | |
# Function to convert any type of data into binary | |
def to_bin(data): | |
"""Used to convert payload and pixel values to binary in payload hiding and extracting phase""" | |
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(ord(i), "08b") for i in data ] | |
elif isinstance(data, int) or isinstance(data, np.uint8): | |
return format(data, "08b") | |
else: | |
raise TypeError("Datatype not supported.") | |
# Function to hide secret_data into the image | |
def encode(image_name, secret_data): | |
image = cv2.imread(image_name) # Read the image | |
n_bytes = image.shape[0] * image.shape[1] * 3 // 8 # Maximum bytes to encode | |
print("[*] Maximum bytes to encode:", n_bytes) | |
secret_data += "=====" # add stopping criteria | |
if len(secret_data) > n_bytes: | |
raise ValueError("[!] Insufficient bytes, need bigger image or less data.") | |
print("[*] Encoding data...") | |
data_index = 0 | |
binary_secret_data = to_bin (secret_data) # convert data to binary | |
data_len = len(binary_secret_data) # size of data to hide | |
for row in image: | |
for pixel in row: | |
r, g, b = to_bin (pixel) # Convert RGB values to binary format | |
if data_index < data_len: # Modify the least significant bit only if there is still data to store | |
pixel[0] = int(r[:-1] + binary_secret_data[data_index], 2) # Least significant red pixel bit | |
data index += 1 | |
if data_index < data_len: | |
pixel[1] = int(g[-1] + binary_secret_data[data_index], 2) # Least significant green pixel bi | |
data index += 1 | |
if data_index < data_len: | |
pixel[2] = int(b[:-1] + binary_secret_data[data_index], 2) # Least significant blue pixel bit | |
data index += 1 | |
if data_index >= data_len: # Break out of the loop if data is encoded | |
break | |
return image | |
# Function to extract secret_data from the 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] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment