#Task 2:
# Define the Polybius  as a matrix
polybius <- matrix(
  c("", "Z", "M", "D", "", "K", "W", "Q", "", "G",
    "V", "", "A", "", "R", "", "E", "", "T", "O",
    "", "J", "I", "S", "B", "P", "Y", "", "F", "",
    "L", "", "", "C", "", "U", "H", "N", "", "X"),
  nrow = 4, byrow = TRUE
)

# Define row and column names for the matrix
row_names <- 0:3
col_names <- 0:9
#Task2:
#Step2.1:Getting the coordinates for the message and keyword using the Polybius matrix
# Define the message and keyword for encryption
message <- c("R", "A", "I", "S", "E", "T", "H", "E", "F", "L", "A", "G")
keyword <- c("A", "P", "P", "L", "E")

# Function to get coordinates of a character in the Polybius square
get_coordinates <- function(char) {
  for (a in 1:4) {
    for (b in 1:10) {
      if (polybius[a, b] == char) {
        return(c(a - 1, b - 1))  # Return 0-based indices
      }
    }
  }
  return(NA)  # Return NA if character not found
}

# Get coordinates for the message and keyword
message_coords <- lapply(message, get_coordinates)
keyword_length <- length(keyword)
keyword_coords <- lapply(rep(keyword, length.out = length(message)), get_coordinates)

# Encrypt the message using the keyword
ciphertext <- c()
for (a in 1:length(message)) {
  message_coord <- message_coords[[a]]
  keyword_coord <- keyword_coords[[a]]
  
  # Calculate adjusted row and column indices
  adjusted_row <- (message_coord[1] + keyword_coord[1]) %% 4
  adjusted_col <- (message_coord[2] + keyword_coord[2]) %% 10
  
  # Combine indices into a ciphertext code
  code <- paste0(adjusted_row, adjusted_col)
  ciphertext <- c(ciphertext, code)
}

# Format ciphertext into groups of 5 characters
ciphertext_str <- paste(ciphertext, collapse = "")
finaltext <- c()
for (a in seq(1, nchar(ciphertext_str), by = 5)) {
  group <- substr(ciphertext_str, a, a + 4)
  finaltext <- c(finaltext, group)
}
print(finaltext)

#Task2:
#Step3.1:Define the given ciphertext for decryption
# Create the Polybius matrix used for encoding and decoding messages
polybius <- matrix(c(" ", "Z", "M", "D", " ", "K", "W", "Q", " ", "G", 
                     "V", " ", "A", " ", "R", " ", "E", " ", "T", "O", 
                     " ", "J", "I", "S", "B", "P", "Y", " ", "F", " ", 
                     "L", " ", " ", "C", " ", "U", "H", "N", " ", "X"), 
                   nrow = 4, byrow = TRUE) # Define the matrix with 4 rows and fill it row by row

# Assign row names (0 to 3) to the Polybius matrix
rownames(polybius) <- 0:3  
# Assign column names (0 to 9) to the Polybius matrix
colnames(polybius) <- 0:9  

# Define the ciphertext to decode (a string of paired numbers separated by spaces)
ciphertext <- "48521 82559 53320 83151 44382 13349 40352 42260 48521 84349 48343 23518"
# Define the keyword used for decoding
keyword <- "LEMON"

# Initialize an empty vector to store ciphertext number pairs
ciphertext_pairs <- c()
# Loop through the ciphertext in steps of 2 to extract paired numbers
for (a in seq(1, nchar(gsub(" ", "", ciphertext)), by = 2)) {
  pair <- substring(gsub(" ", "", ciphertext), a, a + 1) # Extract a pair of digits
  ciphertext_pairs <- c(ciphertext_pairs, as.numeric(pair))  # Add the numeric pair to the vector
}

# Initialize an empty vector to store numeric values of the keyword
keyword_numeric <- c()
# Split the keyword into individual characters
keyword_chars <- unlist(strsplit(keyword, ""))
# Loop through each character of the keyword
for (char in keyword_chars) {
  for (row in 0:3) {   # Iterate over rows (0 to 3) of the Polybius matrix
    for (col in 0:9) {  # Iterate over columns (0 to 9) of the Polybius matrix
      if (polybius[row + 1, col + 1] == char) {  # If the matrix element matches the character
        keyword_numeric <- c(keyword_numeric, row * 10 + col) # Convert row and column to numeric and store
      }
    }
  }
}

# Initialize an empty string to store the plaintext message
plaintext <- ""
# Loop through each numeric pair in the ciphertext
for (a in seq_along(ciphertext_pairs)) {
  cipher_value <- ciphertext_pairs[a] # Get the current ciphertext value
  key_adjustment <- keyword_numeric[(a - 1) %% length(keyword_numeric) + 1] # Get the corresponding keyword adjustment value
  
  adjusted_value <- cipher_value - key_adjustment  # Subtract the keyword adjustment from the ciphertext value
  row <- floor(adjusted_value / 10)   # Compute the row index from the adjusted value
  col <- adjusted_value %% 10   # Compute the column index from the adjusted value
  
  # Check if the row and column indices are within the valid range of the Polybius matrix
  if (row >= 0 && row <= 3 && col >= 0 && col <= 9) {
    letter <- polybius[row + 1, col + 1]  # Retrieve the character from the matrix
    if (letter != " ") {   # Skip empty spaces in the matrix
      plaintext <- paste0(plaintext, letter)  # Append the character to the plaintext
    }
  }
}

# Print the final decoded plaintext message
plaintext