knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%" )
HOQCenc is an R package containing routines for encryption and decryption of character strings and files. The main function is xcode
that encrypts an input string by executing a number of operations (specified by argument trans
) when argument ed='e'
. When ed='d'
is specified decryption will be done by executing the operations in reversed order.
You can install this version from GitHub with:
# install.packages("devtools") devtools::install_github("HanOostdijk/HOQCenc",build_vignettes=TRUE)
library(HOQCenc)
In the Details section more examples are given and some background. In this first example we show:
key <- "1VerySecretKey" message1 <- "Line 1 of a two-line message!\nAs expected a second line." message2 <- "Line 1 of a two-line message.\nAs expected a second line." (s <- xcode(message1,key=key,ed='e',trans='cscvp')) # encrypt message1 xcode(s,key=key,ed='d',trans='cscvp') # show result of decryption xcode(message2,key=key,ed='e',trans='cscvp') # encrypt message2
When we specify key=''
an ordered set is constructed consisting of the lower and upper case letters, the digits 0 till 9 and the space and the #
character. This ordered set is our 'alphabet': all operations will work only with this set with the exception of the e
operation that converts our standard symbols to this new alphabet.
When we use the key 1VerySecretKey
the characters in this key will be inserted in this set before the others so that the following ordered set will be constructed:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [1,] "1" "V" "e" "r" "y" "S" "c" "t" [2,] "K" "a" "b" "d" "f" "g" "h" "i" [3,] "j" "k" "l" "m" "n" "o" "p" "q" [4,] "s" "u" "v" "w" "x" "z" "A" "B" [5,] "C" "D" "E" "F" "G" "H" "I" "J" [6,] "L" "M" "N" "O" "P" "Q" "R" "T" [7,] "U" "W" "X" "Y" "Z" "0" "2" "3" [8,] "4" "5" "6" "7" "8" "9" " " "#"
In almost all operations (but not the e
, s
and f
operation) this 'alphabet' will be used.
The following operations are defined (we describe only what happens in case of encryption because for decryption the reversed action is performed):
0123456789abcdef
is translated to 0f2d4b6987a5c3e1
0123456789abcdef
is translated to fedcba9876543210
mode='ECB'
The encryption characteristics of these operations are the following:
v
, p
or a
operationsSo it is advised to combine several options as e.g. done in the example below
key <- "1VerySecretKey" # small differences in text lead to similar outcomes with simple trans xcode("abcdefghijklmnopqrstuwvxyz",key=key,ed='e',trans='p') xcode("1bcdefghijklmnopqrstuwvxyz",key=key,ed='e',trans='p') xcode("abcdefghijklmnopqrstuwvxy1",key=key,ed='e',trans='p') xcode("ABabcdefghijklmnopqrstuwvxy1",key=key,ed='e',trans='p') # small differences in text lead to unrelated outcomes with complex trans xcode("abcdefghijklmnopqrstuwvxyz",key=key,ed='e',trans='cscvp') xcode("1bcdefghijklmnopqrstuwvxyz",key=key,ed='e',trans='cscvp') xcode("abcdefghijklmnopqrstuwvxy1",key=key,ed='e',trans='cscvp') xcode("ABabcdefghijklmnopqrstuwvxy1",key=key,ed='e',trans='cscvp')
e
operationMost of the operations used in the xcode
function are working only at the 64 characters of our ordered set of the lower and upper case letters, the digits 0 till 9 and the space and the #
character.
The e
operation:
#
character and the characters outside the ordered set by replacing each of those by #
and their hex representation. E.g. the exclamation mark is replaced by #21
and the #
character itself is replaced by #23
.#00
) and possible one or two spaces. The multiple of 16 is necessary when the a
operation (AES encryption) is used but for the other operations an even number of characters is sufficient.Because the e
operation is necessary for most cases it is always prefixed to the list of operations that is specified in the trans
argument.
xcode('Deze #!',key='',ed='e',trans='')
xcode('example!',key='',ed='e',trans='') xcode('example!',key='',ed='e',trans='p') xcode('example!',key='',ed='e',trans='a')
Only when the noe
argument is explicitly set to TRUE
this is not done.
xcode('example!',key='',ed='e',trans='',noe=T) xcode('example!',key='',ed='e',trans='p',noe=T) xcode('example ',key='',ed='e',trans='p',noe=T) # but with space instead of ! xcode('example ',key='',ed='e',trans='a',noe=T)
p
operationWith the p
operation a Playfair transformation is done that acts on pairs of characters.
With key=''
the following 'alphabet' is used
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [1,] "a" "b" "c" "d" "e" "f" "g" "h" [2,] "i" "j" "k" "l" "m" "n" "o" "p" [3,] "q" "r" "s" "t" "u" "v" "w" "x" [4,] "y" "z" "A" "B" "C" "D" "E" "F" [5,] "G" "H" "I" "J" "K" "L" "M" "N" [6,] "O" "P" "Q" "R" "S" "T" "U" "V" [7,] "W" "X" "Y" "Z" "0" "1" "2" "3" [8,] "4" "5" "6" "7" "8" "9" " " "#"
and therefore "ex" is converted to "hu' because 'h' and 'u' lie on the opposite corner of the rectangle though 'e' and 'x'. Special cases:
Advantage of Playfair is that a frequency distribution on character level makes little sense because the method works on pairs of characters.
xcode('example ',key='',ed='e',trans='p',noe=T) xcode("hueiimg8",key='',ed='d',trans='p',noe=T)
s
and f
operationsThe s
(shuffle) operation shuffles the characters in such a way that 0123456789abcdef
is translated to 0f2d4b6987a5c3e1
and the f
(flip) operation flips the characters in such a way that 0123456789abcdef
is translated to fedcba9876543210
.
xcode('0123456789abcdef',key='',ed='e',trans='s',noe=T) xcode('0123456789abcdef',key='',ed='e',trans='f',noe=T)
v
operationThe v
(Vigenère) operation shifts the i-th character a number of places in the 'alphabet'. That number is determined by the position of the i-th letter in the 'alphabet'. In the first example the 'alphabet' is ABCabcdef ...
and therefore the shifts for the letters 'a', 'b' etc. are 4, 5 etc. resulting in '4', '6' etc. In the second example the 'alphabet' is abcdef ...
and therefore the shifts for the letters 'a', 'b' etc. are 1, 2 etc. resulting in '1', '3' etc.
xcode('0123456789abcdef',key='ABC',ed='e',trans='v',noe=T) xcode('0123456789abcdef',key='abc',ed='e',trans='v',noe=T)
c
operationThe c
operation shifts the first character a number of places in the 'alphabet'. That number is again determined by the position of the first letter in the 'alphabet'. In the first example the 'alphabet' is abcdef ...
and therefore the shifts for the letter 'a' is 1 resulting in '1' . The shift for the next position is therefore determined by the position of '1' in the 'alphabet' and that is 44. So the next position (the '1') is shifted by 44 positions in the 'alphabet' resulting in 'R' . And so on ...
The main advantage of this method is that the encryption of a character is determined by all of its predecessors. The weak point is that only the position of the 'a' in the 'alphabet' has to be guessed or tried by brute force and this is very easy. So this method should never be used on its own.
xcode('0123456789abcdef',key='abc',ed='e',trans='c',noe=T)
a
operationThe a
uses the digest::AES
function with the mode='ECB'
method. The method works in blocks of 16 characters: blocks that are identical with the exception of one character will be encrypted to very unrelated results. However if a block occurs more than once, each block is identically encrypted. So also this method should never be used on its own.
xcode('0123456789abcdef',key='abc',ed='e',trans='a',noe=T) xcode('1123456789abcdef',key='abc',ed='e',trans='a',noe=T) xcode('0123456789abcdee',key='abc',ed='e',trans='a',noe=T) xcode('0123456789abcdef0123456789abcdef',key='abc',ed='e',trans='a',noe=T)
h
operationThe h
uses the Hill
transformation. The method works in blocks of 4 characters: blocks that are identical with the exception of one character will be encrypted to very unrelated results. Each character is transformed to its rank in the ordered set. A linear transformation is then done on these four numbers by applying a matrix multiplication and the resulting numbers (modulo 64) are used as rank numbers in the ordered set to determine the four output characters. The matrix used is a fixed matrix. The examples show (again) that it is necessary to combine this operation with other ones to make it more safe.
xcode('0123456789abcdef',key='abc',ed='e',trans='h',noe=T) xcode('1123456789abcdef',key='abc',ed='e',trans='h',noe=T) xcode('0123456789abcdee',key='abc',ed='e',trans='h',noe=T) xcode('0123456789abcdef0123456789abcdef',key='abc',ed='e',trans='h',noe=T)
The xcode
function can also handle raw vectors
text <- "this will be raw text" (textraw <- charToRaw(text)) (s<-xcode(textraw,key='abc',ed='e',trans='cscp')) (s<-xcode(s,key='abc',ed='d',trans='cscp')) rawToChar(s)
To ease reading and writing of files with and without encryption four functions are defined:
write_enc_ascfile
and read_enc_ascfile
when handling asci (standard text) datawrite_enc_binfile
and read_enc_binfile
when handling binary dataTo demonstrate the various possibilities we first define text to work on and generate the name of a test file:
text <- "This is a 21st century example of an English text." textraw <- charToRaw(text) tfile <- tempfile(pattern = "file", tmpdir = tempdir(), fileext = ".txt")
Example of working with asci text (remember that the encrypted text is always asci):
# write asci with encoding write_enc_ascfile(text,tfile,encode=T) # read without decoding (read_enc_ascfile(tfile,decode=F)) # read with decoding (read_enc_ascfile(tfile,decode=T))
Again asci text but now using the binary mode functions:
# write asci in binary mode with encoding write_enc_binfile(text,tfile,encode=T) # read without decoding and no raw -> character conversion (read_enc_binfile(tfile,decode=F,raw2char=F)) # read without decoding and with raw -> character conversion (read_enc_binfile(tfile,decode=F,raw2char=T)) # read with decoding and no raw -> character conversion (read_enc_binfile(tfile,decode=T))
Now with binary data and therefore the write_enc_binfile
and read_enc_binfile
functions must be used:
# write raw text binary mode with encoding write_enc_binfile(textraw,tfile,encode=T) # read without decoding and no raw -> character conversion (read_enc_binfile(tfile,decode=F,raw2char=F)) # read without decoding and with raw -> character conversion (read_enc_binfile(tfile,decode=F,raw2char=T)) # read with decoding and no raw -> character conversion (read_enc_binfile(tfile,decode=T,raw2char=F)) # read with decoding and with raw -> character conversion (read_enc_binfile(tfile,decode=T,raw2char=T))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.