The latest version of StegosauR
can be downloaded from
my GitHub page.
Using it is fairly easy.
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.
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.
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