Guest User

Untitled

a guest
Mar 18th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.88 KB | None | 0 0
  1. rm(list=ls())
  2.  
  3. #### CIPHER AND DECIPHER ----------------------------------------
  4.  
  5. ## Create a cipher string from integer key nums
  6. numCipherString <- function(num)
  7. {
  8. letters <- sapply(LETTERS, utf8ToInt)
  9. letters <- suppressWarnings((letters + num - 65) %% 26 + 65)
  10. cipher <- sapply(letters, intToUtf8)
  11. return(paste(cipher, collapse = ""))
  12. }
  13.  
  14. ## Generate random cipher string
  15. randomCipherString <- function()
  16. {
  17. return(paste(sample(LETTERS, 26), collapse = ""))
  18. }
  19.  
  20. ## Create a vector that associates alphabet with cipher string
  21. createCipher <- function(cipherString)
  22. {
  23. cipherKey <- strsplit(toupper(cipherString), split = "")[[1]]
  24.  
  25. if ( length(cipherKey) != 26 ) {
  26. stop("cipher string must have 26 characters")
  27. }
  28.  
  29. cipher <- vector(mode = "numeric", length = 26+1)
  30. names(cipher) <- c(LETTERS, " ")
  31. cipher[LETTERS] <- cipherKey
  32. cipher[" "] <- " "
  33. return(cipher)
  34. }
  35.  
  36. ## Apply the cipher to a text
  37. applyCipher <- function(text, cipherString)
  38. {
  39. cipher <- createCipher(cipherString)
  40.  
  41. # check is upper case alphabetic or whitespace
  42. text <- strsplit(toupper(text), split = "")[[1]]
  43. in.alphabet <- sapply(text, function(x) {isTRUE(grep("[A-Z]", x) == 1)})
  44. text[!in.alphabet] <- " "
  45.  
  46. return(paste(as.character(cipher[text]), collapse = ""))
  47. }
  48.  
  49. ## Decipher text given a cipher string
  50. applyDecipher <- function(text, cipherString)
  51. {
  52. cipher <- createCipher(cipherString)
  53. decipher <- c(LETTERS, " ")
  54. names(decipher) <- cipher
  55.  
  56. # check is upper case alphabetic or whitespace
  57. text <- strsplit(toupper(text), split = "")[[1]]
  58. in.alphabet <- sapply(text, function(x) {isTRUE(grep("[A-Z]", x) == 1)})
  59. text[!in.alphabet] <- " "
  60.  
  61. return(paste(as.character(decipher[text]), collapse = ""))
  62. }
  63.  
  64.  
  65.  
  66. ### CODE BREAKING -------------------------------------
  67.  
  68. ## COunt the appearance of each letter pair in the text (e.g. "TH" and "ES")
  69. getLanguageCounts <- function(longtext.path)
  70. {
  71. counts <- list()
  72.  
  73. # read line by line
  74. con <- file(longtext.path, "r")
  75. while( TRUE ) {
  76. line <- readLines(con, n = 1)
  77. if ( length(line) == 0 ) break;
  78.  
  79. # check is upper case alphabetic or whitespace
  80. line <- strsplit(toupper(line), split = "")[[1]]
  81. in.alphabet <- sapply(line, function(x) {isTRUE(grep("[A-Z]", x) == 1)})
  82. line[!in.alphabet] <- " "
  83.  
  84. pairs <- paste(line[-length(line)],line[-1], sep = "")
  85. pairs <- table(pairs)
  86.  
  87. old <- names(pairs) %in% names(counts)
  88. old.names <- names(pairs)[old]
  89. new.names <- names(pairs)[!old]
  90.  
  91. counts[old.names] <- as.numeric(counts[old.names]) +
  92. as.numeric(pairs[old.names])
  93. counts[new.names] <- as.numeric(pairs[new.names])
  94. }
  95. close(con)
  96.  
  97. return(counts)
  98. }
  99.  
  100.  
  101. ## same as getLanguageCounts but for shorter text not in file
  102. getCounts <- function(text)
  103. {
  104. # check is upper case alphabetic or whitespace
  105. text <- strsplit(toupper(text), split = "")[[1]]
  106. in.alphabet <- sapply(text, function(x) {isTRUE(grep("[A-Z]", x) == 1)})
  107. text[!in.alphabet] <- " "
  108.  
  109. pairs <- paste(text[-length(text)],text[-1], sep = "")
  110.  
  111. return(as.list(table(pairs)))
  112. }
  113.  
  114.  
  115. scoreCipher <- function(text, cipherString, languageCounts )
  116. {
  117. #cipher <- createCipher(cipher)
  118. decrypted <- applyDecipher(text, cipherString)
  119. counts <- getCounts(decrypted)
  120. score <- 0
  121.  
  122. for (pair in intersect( names(counts), names(languageCounts) ) )
  123. {
  124. c <- as.numeric(counts[pair])
  125. l <- as.numeric(languageCounts[pair])
  126. score <- score + c*log(l)
  127. }
  128.  
  129. return(score)
  130. }
  131.  
  132.  
  133. swapCipher <- function( cipherString )
  134. {
  135. index <- sample(1:nchar(cipherString), 2)
  136. cipherVec <- strsplit(toupper(cipherString), split = "")[[1]]
  137.  
  138. swap1 <- cipherVec[index[1]]
  139. cipherVec[index[1]] <- cipherVec[index[2]]
  140. cipherVec[index[2]] <- swap1
  141.  
  142. return(paste(cipherVec, collapse = ""))
  143. }
  144.  
  145. # Biased coin with probability p of heads
  146. biasedCoin <- function(p)
  147. {
  148. return(runif(1,0,1) < p)
  149. }
  150.  
  151.  
  152. crackMCMC <- function(n, text, languageCounts)
  153. {
  154. currentCipher <- randomCipherString()
  155. memory <- list()
  156. bestCipher <- currentCipher
  157. score <- 0
  158. for ( i in 1:n )
  159. {
  160. memory[i] <- currentCipher
  161. nextCipher <- swapCipher( currentCipher )
  162.  
  163. currentScore <- scoreCipher(text, currentCipher, languageCounts)
  164. nextScore <- scoreCipher(text, nextCipher, languageCounts)
  165.  
  166. p.accept <- min(1, exp(nextScore - currentScore))
  167.  
  168. if ( currentScore > score )
  169. {
  170. bestCipher <- currentCipher
  171. }
  172. if ( biasedCoin(p.accept) )
  173. {
  174. currentCipher <- nextCipher
  175. }
  176. if ( i %% 500 == 0 )
  177. {
  178. cat("iter ", i, ": ", substr(applyDecipher(text, currentCipher),1,99),"\n")
  179. }
  180. }
  181.  
  182. return(list(best = bestCipher, memory = memory))
  183. }
  184.  
  185.  
  186.  
  187. ### TESTING ### -----------------------------------------------------
  188. text <- paste("As Oliver gave this first proof",
  189. "of the free and proper action of his lungs",
  190. "the patchwork coverlet which was carelessly",
  191. "flung over the iron bedstead, rustled;",
  192. "the pale face of a young woman was raised",
  193. "feebly from the pillow; and a faint voice",
  194. "imperfectly articulated the words, Let me",
  195. "see the child, and die. The surgeon had been",
  196. "sitting with his face turned towards the fire:",
  197. "giving the palms of his hands a warm and a rub",
  198. "alternately. As the young woman spoke, he rose,",
  199. "and advancing to the bed's head, said, with more",
  200. "kindness than might have been expected of him: ")
  201.  
  202. ## Use the text of any large book here, e.g. War and Peace.
  203. languageCounts <- getLanguageCounts("warandpeace.txt")
  204.  
  205. cipher <- "XEBPROHYAUFTIDSJLKZMWVNGQC"
  206.  
  207. encrypted.text <- applyCipher(text, cipher)
  208.  
  209. cat("Text To Decode:", encrypted.text, "\n")
  210. result = crackMCMC(10000, encrypted.text, languageCounts)
  211. cat("\n", "Decoded Text:", applyDecipher(encrypted.text, result["best"]), "\n")
  212. cat("MCMC KEY FOUND:", result["best"], "\n")
  213. cat(" ACTUAL KEY:", cipher, "\n")
Add Comment
Please, Sign In to add comment