Αυτό το script, αποκρύπτει αρχεία μέσα σε εικόνες (currenlty PNG) και εξάγει την τροποποιημένη εικόνα στο δίσκο σας.
Το μέγιστο μέγεθος αρχείου που μπορεί να κρυφτεί μέσα σε μια εικόνα εξαρτάται από τη διάσταση της εικόνας.
max_file_size = ( height_of_image * width_of_image * 6 / 8 ) bytes
Το “100k words.txt” είναι κρυμμένο στο “original_image.png” που ονομάζεται “image_with_100k words.png”. Πηγαίνετε και ελέγξτε εάν μπορείτε να εντοπίσετε τη διαφορά μεταξύ αυτών των δύο εικόνων. Μπορείτε να χρησιμοποιήσετε αυτήν την ενότητα για να εξαγάγετε “100k words.txt” από το “image_with_100k words.png”.
Παράδειγμα αρχικής εικόνας:
Τροποποιημένη εικόνα
Αυτή η εικόνα έχει 100k λέξεις κρυμμένες μέσα της!
Πως δουλεύει;
Βασίζεται σε μια απλή αρχή ότι αν αλλάξουμε το LSB (Least Significant Bits) κάθε Pixel, τότε η αλλαγή δεν θα είναι σημαντική και δεν θα παρατηρηθεί με γυμνά μάτια.
Έτσι, αυτή η ενότητα παίρνει 2 bit δεδομένων από το αρχείο για να κρυφτεί και αντικαθιστά τα τελευταία 2 bit ενός pixel με αυτά τα 2 bit και στη συνέχεια, μεταβαίνει στο επόμενο pixel.
Η μέγιστη αλλαγή σε pixel μπορεί να είναι 4 μονάδες και το εύρος τιμών σε εικόνα PNG (0,255), επομένως αυτή η αλλαγή δεν είναι σημαντική.
Σε μια εικόνα PNG, κάθε εικονοστοιχείο έχει 3 κανάλια κόκκινο, πράσινο και μπλε. (Ορισμένες εικόνες PNG έχουν 1 ή 4 κανάλια, αλλά αυτό το πρόγραμμα θα τις μετατρέψει σε 3 κανάλια) Ένα τυπικό pixel σε εικόνα PNG μοιάζει με:
a_pixel = (17,32,11) # (RED, GREEN, BLUE)
Έτσι, μπορούμε να εξοικονομήσουμε 3 φορές 2 bit σε ένα Pixel, που σημαίνει 6 bit ανά pixel. Αυτό μας οδηγεί στο ανώτερο όριο του μεγέθους του αρχείου, το οποίο μπορεί να κρυφτεί σε μια εικόνα:
max_file_size = ( height_of_image * width_of_image * 6 / 8 ) bytes
Ας το καταλάβουμε με ένα παράδειγμα. Τα δεδομένα που θα κρυφτούν είναι:
binary_data = 0b100111
Ας πάρουμε τα πρώτα δύο bits και θα τα αντικαταστήσουμε με το RED Channel του «a_pixel» μας.
a_pixel = (0b10001, 0b100000, 0b1011) # binary representation of a_pixel values # Let's change a_pixel's RED Channel # 0b10001 -> 0b10010 ( First 2 bits are 10 ) a_pixel = (0b10010, 0b100000, 0b1011) # modified pixel
Ας πάρουμε πάλι 2 bit από το binary_data για να αντικαταστήσουμε τα τελευταία 2 bit του GREEN Channel με αυτά.
a_pixel = (0b10010, 0b100000, 0b1011) # Let's change a_pixel's GREEN Channel # 0b100000 -> 0b100001 ( The 2 bits are 01 ) a_pixel = (0b10010, 0b100001, 0b1011) # modified pixel
Ας το κάνουμε για άλλη μια φορά με το BLUE Channel και τελειώσαμε.
a_pixel = (0b10010, 0b100001, 0b1011) # Let's change a_pixel's BLUE Channel # 0b1011 -> 0b1011 ( The 2 bits are 11 ) ; Notice that the value wasn't changed this time a_pixel = (0b10010, 0b100001, 0b1011) # pixel wasn't modified this time
Έτσι, έχουμε κρύψει ένα μήνυμα 6 bit σε ένα pixel. Ας δούμε τις αλλαγές στο pixel
a_pixel = (0b10001, 0b100000, 0b1011) = (17, 32, 11) a_pixel_with_data = (0b10010, 0b100001, 0b1011) = (18, 33, 11)
Όπως μπορούμε να δούμε ότι η αλλαγή δεν είναι καν αισθητή στο επίπεδο των pixel. Το Module το κάνει επανειλημμένα έως ότου όλα τα δεδομένα μας αποθηκευτούν στην εικόνα.
ΣΗΜΕΙΩΣΗ: Ο “θόρυβος” στη φωτογραφία αυξάνεται και εάν χρησιμοποιήσουμε οποιοδήποτε λογισμικό επεξεργασίας φωτογραφιών για να την συγκρίνουμε με την αρχική εικόνα, τότε αυτή η εικόνα θα έχει πολύ περισσότερο θόρυβο από την αρχική εικόνα.
Πολύ έξυπνος τρόπος για να χώσουμε μηνύματα σε εικόνες !!!