-
-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathaffine-cipher.R
More file actions
67 lines (54 loc) · 1.37 KB
/
affine-cipher.R
File metadata and controls
67 lines (54 loc) · 1.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# normalise function
# - remove whitespace
# - make all lower case
normalise<-function(text){
return(tolower(gsub(" ", "", text)))
}
#lookup index of letter
lookupIndex<-function(normalisedtext){
# list of letters
letterslist <- strsplit(normalisedtext, "")[[1]]
# index of letters
return(match(letterslist, letters) - 1)
}
#find gcd
gcd <- function(x, y) {
r <- x %% y
return(ifelse(r, gcd(y, r), y))
}
# computes the modulo multiplicative inverse of a^m
# a^-1 = mmi( a mod m)=mmi(a,m)
mmi <- function(a, m) {
a <- a %% m
for (x in 1:m) {
if ((a * x) %% m == 1) {
return(x)
}
}
return(1)
}
# encrypts plaintext
encrypt <- function(plaintext, a, b) {
m <- 26
# must check a and m are coprime
if (gcd(a, m) != 1) {
stop(paste('a=',a,' and m=',m,'is coprime'))
}
#normalise text input
normalisedplaintext<-normalise(plaintext)
x<-lookupIndex(normalisedplaintext)
# E(x) = (ax + b) mod m
return(paste(letters[ ((a * x + b) %% m) + 1], collapse = ""))
}
# decrypts encryption
decrypt <- function(encryption, a, b) {
m <- 26
# must check a and m are coprime
if (gcd(a, m) != 1) {
stop("a and 26 must be co-prime")
}
normalisedencryption<-normalise(encryption)
y<-lookupIndex(normalisedencryption)
# D(y) = a^-1(y - b) mod m
return(paste(letters[((mmi(a, m) * (y - b)) %% m) + 1], collapse = ""))
}