[back to intro] - [to part 1] - [to part 2] - [to part 3] - [Capabilities]

The latest version of StegosauR can be downloaded from my GitHub page. Using it is fairly easy.

Encode a message

After loading the package, it is necessary to pick an image.

#load package
library(StegosauR)

#load an image of choice
img <- "./images/StegosauR/Ginkgo_input.jpg"

For this example I chose this pic of Ginkgo leaves shamelessly taken from my instagram account.

Ginkgo_Kiel

Now we need a message to encode. L’infinito, an Italian poem written by Giacomo Leopardi in 1819, is not exactly a secret piece of information, but works well for this example.

#message to encode
        txt <-"
        Sempre caro mi fu quest'ermo colle,
        e questa siepe, che da tanta parte
        dell'ultimo orizzonte il guardo esclude.
        Ma sedendo e mirando, interminati
        spazi di là da quella, e sovrumani
        silenzi, e profondissima quïete
        io nel pensier mi fingo; ove per poco
        il cor non si spaura. E come il vento
        odo stormir tra queste piante, io quello
        infinito silenzio a questa voce
        vo comparando: e mi sovvien l'eterno,
        e le morte stagioni, e la presente
        e viva, e il suon di lei. Così tra questa
        immensità s'annega il pensier mio:
        e il naufragar m'è dolce in questo mare.
        "

Pick a password to encrypt your message in a semi-randomized way. If you do not provide any password, StegosauR will automatically use the default one. If this is your choice, then it is not necessary to provide any password during the decoding phase too. Optionally, you can use up to two passwords at the same time. In this case, both passwords will be needed to retrieve the message.

password_1 <- "pick your passwords wisely"

password_2 <- "a second password, why not?"

As a final step, it is sufficient to put all this information together under function encosaur().

#encoding the message

#without any password
#encosaur(input=img, message = txt, output = "./images/StegosauR/Ginkgo_output")

#using only one password
#encosaur(input=img, message = txt, output = "./images/StegosauR/Ginkgo_output", secret=password_1)

#with two passwords
encosaur(input=img, message = txt, output = "./images/StegosauR/Ginkgo_output", secret=password_1, salt=password_2)

Unfortunately .tiff images are not supported by most web browsers, so I can’t show a side-by-side comparison. You can still download the original jpg from here and the encoded tiff from here. From a macroscopic point of view, both images look identical, yet the second one contains out encrypted message.

Decode a message

Recovering an encoded message is done through function decosaur().

#decoding the message

#without password
#decoded_txt <- decosaur(input="./images/StegosauR/Ginkgo_output.tiff")

#with a single password
#decoded_txt <- decosaur(input="./images/StegosauR/Ginkgo_output.tiff", secret=password_1)

#with two passwords
decoded_txt <- decosaur(input="./images/StegosauR/Ginkgo_output.tiff", secret=password_1, salt=password_2)


writeLines(decoded_txt, con = stdout(), sep = "\n", useBytes = FALSE)
## 
##         Sempre caro mi fu quest'ermo colle,
##         e questa siepe, che da tanta parte
##         dell'ultimo orizzonte il guardo esclude.
##         Ma sedendo e mirando, interminati
##         spazi di là da quella, e sovrumani
##         silenzi, e profondissima quïete
##         io nel pensier mi fingo; ove per poco
##         il cor non si spaura. E come il vento
##         odo stormir tra queste piante, io quello
##         infinito silenzio a questa voce
##         vo comparando: e mi sovvien l'eterno,
##         e le morte stagioni, e la presente
##         e viva, e il suon di lei. Così tra questa
##         immensità s'annega il pensier mio:
##         e il naufragar m'è dolce in questo mare.
## 

The decoded message is identical to the original input.

txt == decoded_txt
## [1] TRUE

Of course, the .tiff file weights quite a lot more. The original .jpg weights approximately 17KB, while its .tiff counterpart is 235KB. It is important to notice that the additional weight comes exclusively from the conversion from .jpg to .tiff. The encryption process only replaces some digits within the original file and does not generate any additional data.

StegosauR uses function writeTIFF() from package tiff to produce the encoded .tiff file. The impact of the encryption process on file size can be measured by converting the original .jpg into .tiff using the same procedure.

library(jpeg)
library(tiff)

#load original image
img.jpg <- readJPEG("./images/StegosauR/Ginkgo_input.jpg")

#convert to .tiff
writeTIFF(what = img.jpg, where = "./images/StegosauR/Ginkgo_input.tiff", bits.per.sample = 16L, compression="none", reduce=FALSE)

Getting the size of all images shows that the .tiff files weight the same.

#file size in bytes.
file.size("./images/StegosauR/Ginkgo_input.jpg",
          "./images/StegosauR/Ginkgo_input.tiff",
          "./images/StegosauR/Ginkgo_output.tiff")
## [1]  17280 240174 240174

In case your input file is already in .tiff format, the output file produced by StegosauR might still have a different weight. This is because StegosauR uses a 16-bit format, while other programs might use 8 or 32 ones, and possibly different conversion algorithms too. For example, converting our original .jpg file into .tiff using GIMP v2.8 (no compression applied) produces a 157KB file. Taking this GIMP-generated .tiff and re-saving it as .tiff using function writeTIFF() results in a 313KB file. I did not check yet what might be the exact cause behind this increase in weight.

library(tiff)

#load .tiff file prodiced with GIMP v2.8
img.tiff <- readTIFF("./images/StegosauR/Ginkgo_input_gimp.tiff")

#re-save it using writeTIFF()
writeTIFF(what = img.tiff, where = "./images/StegosauR/Ginkgo_output_gimp.tiff", bits.per.sample = 16L, compression="none", reduce=FALSE)
#file size in bytes.
file.size("./images/StegosauR/Ginkgo_input_gimp.tiff",
          "./images/StegosauR/Ginkgo_output_gimp.tiff")
## [1] 160368 320176
[back to intro] - [to part 1] - [to part 2] - [to part 3] - [Capabilities]