# Written by Yuxuan Zhao
rm(list = ls())

#Create a matrix Polybius that contains the character data.
Polybius <- matrix(c(NA,"Z","M","D",NA,"K","W","Q",NA,"G",
                     "V",NA,"A",NA,"R",NA,"E",NA,"T","O",
                     NA,"J","I","S","B","P","Y",NA,"F",NA,
                     "L",NA,NA,"C",NA,"U","H","N",NA,"X"), 
                   ncol=10, byrow = TRUE, dimnames = list(format(0:3), format(0:9)))

# Task2.2

Message <- 'RAISETHEFLAG'         # Message to be encrypted
len_of_mes <- nchar(Message)      # Get string length
keyword <- 'PEACH'
len_of_key <- nchar(keyword)
cipher_code <- c()
key_code <- c()



# Message is converted into letter code through this loop
for (x in 1:len_of_mes){
  letter <- substring(Message, x, x)
  for (i in 1:4){                 # find the letter code
    for (j in 1:10){
      if ((is.na(Polybius[i,j])!=TRUE)&&((Polybius[i,j])==letter)) {
        cipher_code <- c(cipher_code,(i-1),(j-1)) # save the letter code
      }
    }
  }
}
# print(cipher_code)              # Display cipher_code

#ADD__Keyword is converted into letter code through this loop
for (x in 1:len_of_key){
  letter <- substring(keyword, x, x)
  for (i in 1:4){                 # find the letter code
    for (j in 1:10){
      if ((is.na(Polybius[i,j])!=TRUE)&&((Polybius[i,j])==letter)) {
        key_code <- c(key_code,(i-1),(j-1)) # save the letter code
      }
    }
  }
}
# print(key_code)                 # Display key_code

#ADD__Add keyword to message
cipher_code_mixed <- cipher_code + key_code # Add in order
for (i in 1:len_of_mes*2){        # Carry
  if(cipher_code_mixed[i]>9){
    cipher_code_mixed[i-1] <- cipher_code_mixed[i-1]+1
    cipher_code_mixed[i] <- cipher_code_mixed[i]-10
  }
}

# Calculate the number of random numbers to be added
# Altered__(len_of_mes+len_of_key)
if(((len_of_mes+len_of_key)*2)%%5==0) {
  num_of_random_digits <- 0
} else {
  num_of_random_digits <- 5-((len_of_mes+len_of_key)*2)%%5
}

# add keyword and random digits to cipher_code
random_digits <- sample(0:9,num_of_random_digits,replace = TRUE)
cipher_text <- c(cipher_code_mixed,random_digits)

text_len <- length(cipher_text)
finaltext <- ''
cipher_text_chr <- format(cipher_text)

# Display letter code in groups of five digits
for (x in 1:text_len){
  finaltext <- paste(finaltext,cipher_text_chr[x], sep = "")
  if ((x%%5==0)&&(x!=text_len)){
    finaltext <- paste(finaltext,' ', sep = "")
  }
}
print(finaltext)



# Task2.3
rm(list = ls())

Polybius <- matrix(c(NA,"Z","M","D",NA,"K","W","Q",NA,"G",
                     "V",NA,"A",NA,"R",NA,"E",NA,"T","O",
                     NA,"J","I","S","B","P","Y",NA,"F",NA,
                     "L",NA,NA,"C",NA,"U","H","N",NA,"X"), 
                   ncol=10, byrow = TRUE, dimnames = list(format(0:3), format(0:9)))

cipher_code <- "48521 82559 53320 83151 44382 13349 40352 42260 48521 84349 48343 23518"
keyword <- "LEMON"

cipher_code_len <- nchar(cipher_code)+1
cipher_code_without_space <- ''
for (x in seq(0, cipher_code_len, by=6)){
  group <- substring(cipher_code, x+1, x+5)
  cipher_code_without_space <- paste(cipher_code_without_space, group, sep = "")
}
len_of_cipher_code_without_space <- nchar(cipher_code_without_space)

#ADD__Keyword is converted into letter code through this loop
len_of_key <- nchar(keyword)
key_code <- c()
for (x in 1:len_of_key){
  letter <- substring(keyword, x, x)
  for (i in 1:4){                 # find the letter code
    for (j in 1:10){
      if ((is.na(Polybius[i,j])!=TRUE)&&((Polybius[i,j])==letter)) {
        key_code <- c(key_code,(i-1),(j-1)) # save the letter code
      }
    }
  }
}

# Convert codes to letters
# Altered__minus key_code from cipher_code
Message <- ''
for (x in seq(1, len_of_cipher_code_without_space-1, by=2)){
  L0 <- as.numeric(substring(cipher_code_without_space, x, x+1))
  L1 <- key_code[x%%(len_of_key*2)]*10+key_code[x%%(len_of_key*2)+1]
  num_raw <- L0-L1 # Letter code
  if((num_raw<0)||(num_raw>40)){  # Avoid Problem caused by random numbers
    break 
  }
  Letter <- Polybius[num_raw%/%10+1,num_raw%%10+1] # Get the Letter
  if (is.na(Letter)){             # Avoid NA caused by random numbers
    break
  }
  Message <- paste(Message, Letter, sep = "")
}
print(Message)


