Good day, dear readers.
I am a representative of the typical (for Habr) modern "shkoloty". I am interested in computer-related themes, I know a couple of programming languages, I believe that I understand something about this. But, the post is not about that.
Looking through Habr, I often came across posts on the topic of steganography. As a beginner
(very beginner, well, quite beginner) programmer, this topic interested me with its own, on the one hand, non-obviousness, on the other - relative ease of implementation. Besides, programming practice was getting closer ...
Having lost my mind, I decided to
build my lunapark, with black ... to write my steganography program. My first job will be about this program, the difficulties in writing it and overcoming them.
')
What is the noise about?
I think habra users do not need to explain what steganography is, but just in case, let me give a link to a post describing the main methods of steganography.
Steganography by
MegasAt the moment I use the LSB method, described in more detail in
this post , more precisely - its generalization for the BMP, PNG and WAV formats.
Chapter One, Problem Statement
When you realize that you are inventing another bicycle, first of all you try to think of how it will be different from the bikes of other “inventors” like you. For myself, I highlighted the following points (however, not all of them (so far) have been implemented):
- Support for different file formats
- Support at least basic encryption
- The ability to zasteganograph a file of any format in the steg-container (not yet implemented) .
- Modularity, i.e. the ability for a user with programming skills in Perl to write modules for the operation of this program with other formats (implemented only “internally”, the API is but undocumented) .
- Adequate graphical interface (only the second part of this item is made, the interface came out “graphical”, but, in my opinion, you cannot call it “adequate”)
I chose Perl 5 as the language, the reasons for the choice are purely subjective - I just like the language (although I realize that I would avoid many pitfalls, choosing, for example, C ++).
Chapter Two, pitfalls
1. Work with binary data
The first "stone" was met almost immediately. The LSB method used, is to change the N low bits in each byte. However, Perl does not provide the ability to work with a file as a sequence of bits, data is read at least byte-by-byte.
This difficulty turned out to be the simplest, in a few minutes the str2bin subroutine was written, translating a string of bytes into an array of bits:
sub str2bin ($) { my @bin; my $str = shift; for (my $i=0; $i < length($str); $i++) { @bin = (@bin, split ('', sprintf "%08b", ord(substr($str, $i, 1)))); } return @bin; }
2. Sloppy program
The next few days it went fine, a module was written to work with files in the BMP format, work began on the WAV format. However, in the process of testing, it was noticed that the program unjustifiably long processes messages with a length of a thousand or more characters (for a message of ~ 4500 characters, the recording time was 25 seconds, reading - 60 seconds).
By long smoking manuals, several hundred applications of
MNT , the following was clarified: operations with changing arrays in Perl'e are slow. No, even this:
meeedlennye.That is, a simple replacement
for (my $i=0; $i < length($str); $i++) { @bin = (@bin, split ('', sprintf "%08b", ord(substr($str, $i, 1)))); } return @bin; }
on
for (my $i=0; $i <= $#t; $i++) { $bin .= substr(dec2bin(ord($t[$i])), 24, 8); } return split('', $bin);
reduced the time of reading and writing from 25 seconds and 60 seconds, to 0.135 seconds and 0.230 seconds, respectively, that is
, acceleration was achieved a hundred times !
3. GUI, Perl, Cyril and Methodius
After writing the module for WAV, it was found out that the Tkx toolkit then used to write the GUI could not adequately work with Cyrillic characters in the TextEdit field.
This problem could not be circumvented, as a result of which it was decided to rewrite the graphic part on Win32 :: GUI.
4. Why torment the dead?
Along the way, the words
Megas came to my head more and more often:
But this method has quite a few minuses. First, it applies only to a small number of containers.There was a desire to come up with a method for working with more lively formats. Then came the once read lines of Wikipedia that the PNG format works with lossless compression.
A simple, inelegant, but working idea came to mind:
- Take a PNG image
- Convert it to temporary, in BMP format
- Apply already implemented steganography methods in BMP to the temporary
- Convert a temporary BMP back to PNG
Message decryption is similar, via a temporary BMP.
Chapter Three, Final (with pictures!)
So, the next bike began its life journey.
Lastly, I will give a link to the git-repository of this program (
KaiNS ), and also show the results of its work:
Original png-image
Image-container containing 10903 times repeated line “Hi, Habr!”
Original wav file (1.7 Mb)
Wav-container password - Utter (1.7 Mb)
Git:
git: //github.com/utter-step/KAiNS.git(Requires installed Perl modules: Win32 :: GUI, Imager).Executable file:
KaiNS.exeI thank all those who came to the end of this post for their attention.
I would be happy to hear in the comments opinions on this topic, and I will be glad if someone tells about other steganographic methods that can be implemented.
Thank!
UPD: The comments suggested a
code that works even more efficiently with an array for the str2bin function, as well as a fundamentally more accurate
solution for working with binary data in Perl. I will apply the first, with the second while I understand in the context of this task.