Steganography is the practice of hiding information (text, images, sounds, …) into any kind of medium. The best example probably consists in writing a message on paper using invisible ink. The intended recipient of the message will know where to look and how to reveal its content, while anybody else will not even be aware of its presence. We are not talking about subliminal messages here. Information hidden through steganography is meant to go completely unnoticed.

This whole idea is quite fascinating. Many of us probably tried to write messages with lemon juice as kids. What makes it even more interesting to me is that quite a great deal of hidden data can be stored in common digital images. In synthesis, digital images are composed of pixels. The color of each pixel is defined by different proportions of primary colors (Red, Green and Blue in the RGB model, for instance). This numeric information can be slightly altered by replacing a minute fraction of it with any other numeric sequence. In this way, the color of the pixel will appear largely unchanged, while at the same time hiding a second layer of data.

The R package StegosauR

Effective digital steganography is quite complicated and well beyond my understanding of how digital imaging works, but I can approximate it in a very simplified way with R. This is exactly the purpose of my R package StegosauR: to hide a user-defined text message into a user-defined image. The package can read .jpg, .png or .tiff images, yet the final product is always saved as a .tiff file. Using the .tiff format is ideal for this simple project because it can store information in an uncompressed way. This means that, after planting the hidden message, the numeric values of each pixels are (more or less) not altered by size-reducing algorithms.

The latest version of StegosauR can be downloaded from my GitHub page, which contains also some installation instructions.

Despite its simplicity, it took me quite a bit of space to explain the inner mechanisms of StegosauR. For this reason, I had to split everything into a few different parts: