Created
June 16, 2025 18:33
-
-
Save insaneyilin/90388c32c8e93f5b93bcef3d76e24291 to your computer and use it in GitHub Desktop.
image 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 argparse | |
from PIL import Image | |
def embed_message(image_path, message, output_path): | |
org_img = Image.open(image_path) | |
org_pixelMap = org_img.load() | |
enc_img = Image.new(org_img.mode, org_img.size) | |
enc_pixelsMap = enc_img.load() | |
binary_msg = ''.join(format(ord(char), '08b') for char in message) | |
msg_len = len(binary_msg) | |
msg_index = 0 | |
for row in range(org_img.size[0]): | |
for col in range(org_img.size[1]): | |
r, g, b = org_pixelMap[row, col] | |
if row == 0 and col == 0: | |
msg_len_bin = format(msg_len, '024b') | |
r = int(msg_len_bin[:8], 2) | |
g = int(msg_len_bin[8:16], 2) | |
b = int(msg_len_bin[16:], 2) | |
enc_pixelsMap[row, col] = (r, g, b) | |
elif msg_index < msg_len: | |
r_bin = format(r, '08b') | |
g_bin = format(g, '08b') | |
b_bin = format(b, '08b') | |
new_r_bin = r_bin[:-1] + binary_msg[msg_index] | |
new_r = int(new_r_bin, 2) | |
msg_index += 1 | |
if msg_index < msg_len: | |
new_g_bin = g_bin[:-1] + binary_msg[msg_index] | |
new_g = int(new_g_bin, 2) | |
msg_index += 1 | |
else: | |
new_g = g | |
if msg_index < msg_len: | |
new_b_bin = b_bin[:-1] + binary_msg[msg_index] | |
new_b = int(new_b_bin, 2) | |
msg_index += 1 | |
else: | |
new_b = b | |
enc_pixelsMap[row, col] = (new_r, new_g, new_b) | |
else: | |
enc_pixelsMap[row, col] = (r, g, b) | |
org_img.close() | |
enc_img.save(output_path) | |
enc_img.close() | |
print(f"Message embedded successfully. Encrypted image saved as {output_path}") | |
def extract_message(image_path): | |
enc_img = Image.open(image_path) | |
enc_pixelMap = enc_img.load() | |
binary_msg = "" | |
msg_len = 0 | |
for row in range(enc_img.size[0]): | |
for col in range(enc_img.size[1]): | |
r, g, b = enc_pixelMap[row, col] | |
if row == 0 and col == 0: | |
msg_len = (r << 16) | (g << 8) | b | |
elif msg_len > 0: | |
r_bin = format(r, '08b') | |
g_bin = format(g, '08b') | |
b_bin = format(b, '08b') | |
binary_msg += r_bin[-1] | |
msg_len -= 1 | |
if msg_len > 0: | |
binary_msg += g_bin[-1] | |
msg_len -= 1 | |
if msg_len > 0: | |
binary_msg += b_bin[-1] | |
msg_len -= 1 | |
message = ''.join(chr(int(binary_msg[i:i+8], 2)) for i in range(0, len(binary_msg), 8)) | |
enc_img.close() | |
return message | |
def main(): | |
parser = argparse.ArgumentParser(description="Steganography tool to hide and extract messages in images.") | |
subparsers = parser.add_subparsers(dest="command", required=True, help="Sub-command to run.") | |
# Subparser for the "hide" command | |
hide_parser = subparsers.add_parser("hide", help="Hide a message in an image.") | |
hide_parser.add_argument("-p", "--image", required=True, help="Path to the image file.") | |
hide_parser.add_argument("-f", "--file", required=True, help="Path to the file containing the secret message.") | |
hide_parser.add_argument("-o", "--output", required=True, help="Path to the output image file.") | |
# Subparser for the "extract" command | |
extract_parser = subparsers.add_parser("extract", help="Extract a message from an image.") | |
extract_parser.add_argument("-u", "--image", required=True, help="Path to the image file containing the hidden message.") | |
extract_parser.add_argument("-o", "--output", required=True, help="Path to the output file for the extracted message.") | |
args = parser.parse_args() | |
if args.command == "hide": | |
with open(args.file, "r") as f: | |
message = f.read() | |
embed_message(args.image, message, args.output) | |
elif args.command == "extract": | |
hidden_message = extract_message(args.image) | |
with open(args.output, "w") as f: | |
f.write(hidden_message) | |
print(f"Message extracted successfully. Saved to {args.output}") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment