ROT cipher generator/cracker in R

The ever-clever Alex (my wife, dontcha know) sent me a sweet message of garbled gibberish letters with “ROT-13” at the end of it. Naturally, I googled. She used a ROT-13 cipher, which is a simple letter substitution cipher.

Of course, I could have just written the alphabet down on a piece of paper, taken two minutes, and read her (very sweet, as it turns out) message, but where’s the fun in that? Instead, I wrote an R function to generate or crack ROT-style ciphers.

To use this, you enter two arguments: the cipher text and then an integer indicating how many letters to the right (positive integer) or left (negative integer) the function should look for the “right” letter.

Example: My name, Darrin Rogers, is “yvmmdi mjbzmn” if I substitute each letter with the one 5 to the “left” of it in the alphabet. That message can be decrypted (after loading the function in R) with this code:

rot.n(“yvmmdi mjbzmn”, 5)

You can further test out the function with this string, each character encoded with the letter 9 positions away from it in the alphabet:

“evmvi xfeer xzmv pfl lg, evmvi xfeer cvk pfl xf”

Here’s the code.

No guarantees my code is very good; in fact, I’m sure it has problems and definitely lots of inefficiency. But here it is, anyway 🙂


# rot cipher encrypter/decrypter
# specify how many letters displaced (i.e., before or after cipher letter)

rot.n <- function(x, displacement) {
  # x = string
  # displacement = number of characters to displace (can be + or - I think)

  # get multiplier (1 or -1) for "wrapping" around ends of alphabet later
  dsign <- displacement / abs(displacement)
  # lowercase
   x <- tolower(x)
   # split characters into individuals
   xs <- unlist(strsplit(x, split=""))
   # get number positions (original)
   xn <- sapply(xs, function(n) {
     ifelse(n %in% letters, {
        which(letters == n)
       }, {
   # raw displacement (can go outside 1:26 range)
   xd <- xn + displacement

   # replace with new letternumber index values
   xnn <- sapply(xd, function(d) {
     ifelse(d %in% (1:26), {
        }, {
          d - 26 * dsign

   xl <- letters[xnn]
   xl[which(] <- xs[which(]
   out <- paste(xl, collapse="")




Leave a Reply

Your email address will not be published. Required fields are marked *