Steganografi Örneği

Merhaba arkadaşlar. Geçenlerde steganografi yani veri saklama ile alakalı ufak bir program yazdım, incelemek isteyenler olur diye atıyorum. Bu kod ile resim dosyaları içine herhangi bir metni saklayabiliyoruz, kodun çalışması için pygame modülünün yüklü olması yeterli:

import os; os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = ""
import pygame as pg
import struct

__all__ = ["Image"]

def pack_byte(raw, byte, index):
    s = 0
    for i in raw[index: index+4]:
        bit_2 = (byte & 0b11000000) >> 6
        byte <<= 2
        raw[s+index] = i & 0b11111100 | bit_2
        s += 1

def unpack_byte(raw, index):
    s = 0
    k = 6
    for i in raw[index: index+4]:
        bit_2 = i & 0b11
        s += bit_2 << k
        k -= 2
    return s


class Image():
    def __init__(self, *, surface = None, path = None):
        if path is not None:
            self.image = pg.image.load(path)
        elif surface is not None:
            if not isinstance(surface, pg.Surface):
                raise TypeError("'surface' argument must be instance of <pg.Surface>, not <{}>".format(type(surface).__name__))
            self.image = surface
        else:
            raise ValueError("Neither 'surface' nor 'path' argument passed.")

    def tobuffer(self):
        return self.image.get_buffer().raw

    def size(self):
        return self.image.get_size()

    def frombuffer(self, buffer):
        try:
            return Image(surface = pg.image.frombuffer(buffer, self.size(), "RGBA"))
        except ValueError:
            return Image(surface = pg.image.frombuffer(buffer, self.size(), "RGB"))

    def encry(self, msg, encoding = "utf-8"):
        raw = bytearray(self.tobuffer())
        msg = msg.encode(encoding) if encoding else msg
        if (8 + len(msg)) * 4 > len(raw): raise OverflowError("Image is not big enough for your message.")
        l = len(msg)
        info = struct.pack(">I", l) 
        all_bytes = info + msg
        
        i = 0
        for c in all_bytes:
            pack_byte(raw, c, i)
            i += 4
            
        return self.frombuffer(raw)

    def save(self, path):
        pg.image.save(self.image, path)

    def decrypt(self, decoding = "utf-8"):
        raw = self.tobuffer()
        
        lenght = bytearray(4)
        for i in range(4):
            lenght[i] = unpack_byte(raw, i * 4)
        lenght = struct.unpack(">I", lenght)[0]

        r = bytearray(lenght)
        for j in range(4, lenght + 4):
            r[j-4] = unpack_byte(raw, j*4)
            
        return r.decode(decoding) if decoding else r


Bu kodu module.py dosyasına kaydettiğimizi varsayarsak şu şekilde kullanabiliriz:

from module import Image

resim = Image(path = "resim.png") # resim.png dosyasını açıyoruz

şifreli_resim = resim.encry("Merhaba Dünya") # mesajı resmin içine saklıyoruz
şifreli_resim.save("şifreli.png") # resmi kaydediyoruz

#----
resim = Image(path = "şifreli.png")
mesaj = resim.decrypt() # resimde saklı metni alıyoruz
print(mesaj)

İçine mesajı saklayacağınız resim dosyasını resim.png adı ile kodun bulunduğu dizine atıp kodu çalıştırırsanız ekrana Merhaba Dünya yazıldığını görebilirsiniz.


Not: Eğer resmi jpeg/jpg gibi kayıplı bir dosya formatında kaydederseniz mesajı geri alamazsınız.


Dikkat: Daha önce içine mesaj saklanmamış bir resmi decrypt etmeye (çözmeye) çalışmayın, RAM kullanımı çok hızlı bir şekilde artabiliyor. Henüz bu problemi çözmeye çalışmadım.

2 Beğeni