firts
This commit is contained in:
parent
b8bb38e143
commit
f0ebab285e
140
stenography.py
Normal file
140
stenography.py
Normal file
@ -0,0 +1,140 @@
|
||||
import argparse
|
||||
import os
|
||||
import struct
|
||||
from Crypto.Cipher import AES
|
||||
from PIL import Image
|
||||
|
||||
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
|
||||
if not out_filename:
|
||||
out_filename = in_filename + '.encrypted'
|
||||
|
||||
iv = os.urandom(16)
|
||||
key_length = len(key)
|
||||
if key_length not in (16, 24, 32):
|
||||
if key_length < 16:
|
||||
key = key.ljust(16, '\0')
|
||||
elif key_length < 24:
|
||||
key = key.ljust(24, '\0')
|
||||
else:
|
||||
key = key.ljust(32, '\0')
|
||||
encryptor = AES.new(key, AES.MODE_CBC, iv)
|
||||
|
||||
filesize = os.path.getsize(in_filename)
|
||||
|
||||
with open(in_filename, 'rb') as infile:
|
||||
with open(out_filename, 'wb') as outfile:
|
||||
outfile.write(struct.pack('<Q', filesize))
|
||||
outfile.write(iv)
|
||||
|
||||
while True:
|
||||
chunk = infile.read(chunksize)
|
||||
if len(chunk) == 0:
|
||||
break
|
||||
elif len(chunk) % 16 != 0:
|
||||
chunk += b' ' * (16 - len(chunk) % 16)
|
||||
|
||||
outfile.write(encryptor.encrypt(chunk))
|
||||
|
||||
def decrypt_file(key, in_filename, out_filename=None, chunksize=24*1024):
|
||||
if not out_filename:
|
||||
out_filename = os.path.splitext(in_filename)[0]
|
||||
|
||||
with open(in_filename, 'rb') as infile:
|
||||
filesize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
|
||||
iv = infile.read(16)
|
||||
key_length = len(key)
|
||||
if key_length not in (16, 24, 32):
|
||||
if key_length < 16:
|
||||
key = key.ljust(16, '\0')
|
||||
elif key_length < 24:
|
||||
key = key.ljust(24, '\0')
|
||||
else:
|
||||
key = key.ljust(32, '\0')
|
||||
decryptor = AES.new(key, AES.MODE_CBC, iv)
|
||||
|
||||
with open(out_filename, 'wb') as outfile:
|
||||
while True:
|
||||
chunk = infile.read(chunksize)
|
||||
if len(chunk) == 0:
|
||||
break
|
||||
outfile.write(decryptor.decrypt(chunk))
|
||||
|
||||
outfile.truncate(filesize)
|
||||
|
||||
def hide_text_in_image(text, image_filename, output_filename=None):
|
||||
image = Image.open(image_filename)
|
||||
pixels = image.load()
|
||||
width, height = image.size
|
||||
|
||||
text_length = len(text)
|
||||
text_length = int(text_length)
|
||||
pixels[0, 0] = text_length
|
||||
|
||||
char_index = 0
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
if char_index < text_length:
|
||||
char = text[char_index]
|
||||
ascii_code = ord(char)
|
||||
pixel = pixels[x, y]
|
||||
if isinstance(pixel, tuple) and len(pixel) == 3:
|
||||
red, green, blue = pixel
|
||||
else:
|
||||
continue
|
||||
red = (red & 0xFE) | ((ascii_code >> 7) & 0x01)
|
||||
green = (green & 0xFE) | ((ascii_code >> 6) & 0x01)
|
||||
blue = (blue & 0xFE) | ((ascii_code >> 5) & 0x01)
|
||||
pixels[x, y] = (red, green, blue)
|
||||
char_index += 1
|
||||
else:
|
||||
break
|
||||
|
||||
if not output_filename:
|
||||
output_filename = os.path.splitext(image_filename)[0] + '_hidden.png'
|
||||
image.save(output_filename)
|
||||
|
||||
|
||||
def extract_key_from_image(image_filename):
|
||||
image = Image.open(image_filename)
|
||||
pixels = image.load()
|
||||
width, height = image.size
|
||||
|
||||
text_length = pixels[0, 0][0]
|
||||
|
||||
text = ''
|
||||
char_index = 0
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
if char_index < text_length:
|
||||
pixel = pixels[x, y]
|
||||
if isinstance(pixel, tuple) and len(pixel) == 3:
|
||||
red, green, blue = pixel
|
||||
else:
|
||||
continue
|
||||
ascii_code = ((red & 0x01) << 7) | ((green & 0x01) << 6) | ((blue & 0x01) << 5)
|
||||
char = chr(ascii_code)
|
||||
text += char
|
||||
char_index += 1
|
||||
else:
|
||||
break
|
||||
|
||||
return text
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Скрипт для скрытия и извлечения текста в изображениях методом стенографии.")
|
||||
parser.add_argument("command", choices=["encrypt_file", "decrypt_file", "encrypt_image", "decrypt_image"])
|
||||
parser.add_argument("input", help="Входной файл")
|
||||
parser.add_argument("--output", help="Выходной файл (если не указан, будет использоваться стандартное имя)")
|
||||
args = parser.parse_args()
|
||||
|
||||
key = extract_key_from_image(args.input)
|
||||
|
||||
if args.command == "encrypt_file":
|
||||
encrypt_file(key, args.input, args.output)
|
||||
elif args.command == "decrypt_file":
|
||||
decrypt_file(key, args.input, args.output)
|
||||
elif args.command == "encrypt_image":
|
||||
text = input("Введите текст, который нужно скрыть в изображении: ")
|
||||
hide_text_in_image(text, args.input, args.output)
|
||||
elif args.command == "decrypt_image":
|
||||
print(extract_key_from_image(args.input))
|
Loading…
Reference in New Issue
Block a user