Wolfram Research

Function Repository Resource:

CrackCaesarCipher

Source Notebook

Attempt to crack a Caesar-enciphered message

Contributed by: Sander Huisman

ResourceFunction["CrackCaesarCipher"][string]

attempt to decipher the Caesar-enciphered input string.

ResourceFunction["CrackCaesarCipher"][string,n]

attempt to decipher string and give the first n results.

Details and Options

ResourceFunction["CrackCaesarCipher"] has the following options:
Method Automatic Method used to decipher the message.
Language "English" Language to use for dictionaries and letter frequencies.
"WordValueFunction" StringLength Function for valueing a matched substring.
"DictionaryWords" Automatic List of words to use for a dictionary attack.
Possible forms for the option Method are:
"Dictionary" Sorts possible deciphered messages based on the presence of words from a dictionary.
"LetterFrequency" Sorts possible deciphered messages based on the letter frequencies and compares those with known letter frequencies based on Language.
Automatic If the string has a length smaller or equal to a 100 characters "Dictionary" is used, for texts above a 100 characters "LetterFrequencies" is used.
Dictionaries are known for the languages given by DictionaryLookup[All] with a latin alphabet.
For the method "Dictionary" each word in the dictionary is tested for its presence. Each matched string gets a value according to the option "WordValueFunction". The highest value candidate deciphered message will be returned.
For the method "Dictionary" a custom list of words can also be given using the option "DictionaryWords".
Letter frequencies are known for the following languages: Czech, Danish, Dutch, English, Esperanto, Finnish, French, German, Icelandic, Italian, Polish, Portuguese, Spanish, Swedish, and Turkish. Data is based on https://en.wikipedia.org/wiki/Letter_frequency.
For the method "LetterFrequency" the frequency of the letters is compared to the known letter frequencies for various languages by calculating Pearson’s correlation coefficient between the letter frequency of the message for various shifts and the known letter frequencies for the language given by the option Language.
When n is given, a list of length n is returned. Each element is an Association with 3 keys: "DecipheredString" contains the deciphered string, "Score" gives the score of the decipher, and "Shift" the Caesar shift. The methods "Dictionary" and "LetterFrequency" give different scores, and can not be directly compared.

Examples

Basic Examples

Try to decipher a string:

In[1]:=
ResourceFunction[
 "CrackCaesarCipher"]["Qeb nrfzh yoltk clu grjmp lsbo qeb ixwv ald"]
Out[1]=

Scope

Give the top 5 deciphers of a short Caesar-enciphered message:

In[2]:=
message = ResourceFunction["CaesarCipher"]["go on", 11];
ResourceFunction["CrackCaesarCipher"][message, 5]
Out[3]=

Options

Method

Try to decipher the message using a dictionary attack:

In[4]:=
s = ResourceFunction["CaesarCipher"]["the apple", 11];
ResourceFunction["CrackCaesarCipher"][s, Method -> "Dictionary"]
Out[5]=

Try to decipher the message using a letter frequency attack :

In[6]:=
ResourceFunction["CrackCaesarCipher"][s, Method -> "LetterFrequency"]
Out[6]=

Language

Use another language:

In[7]:=
ResourceFunction["CaesarCipher"]["Mijn naam is Sander!", 11];
ResourceFunction["CrackCaesarCipher"][%, Language -> "Dutch"]
Out[8]=

“WordValueFunction”

The default "WordValueFunction" is the length of the string:

In[9]:=
s = ResourceFunction["CaesarCipher"]["The red car!", 11];
ResourceFunction["CrackCaesarCipher"][s, 4, Method -> "Dictionary", "WordValueFunction" -> StringLength]
Out[10]=

Value each matched string with a different metric. In this case just counting them:

In[11]:=
s = ResourceFunction["CaesarCipher"]["The red car!", 11];
ResourceFunction["CrackCaesarCipher"][s, 4, Method -> "Dictionary", "WordValueFunction" -> (1 &)]
Out[12]=

“DictionaryWords”

Give a custom dictionary in form of a list of strings. If in a piece of text certain words are expected this can speed up the cracking significantly:

In[13]:=
s = ResourceFunction["CaesarCipher"]["my hovercraft is full of eels!",
    11];
ResourceFunction["CrackCaesarCipher"][s, Method -> "Dictionary", "DictionaryWords" -> {"airplane", "truck", "hovercraft", "car", "boat", "plane", "bike", "bicyle", "moped"}]
Out[14]=

Applications

Decipher a long text:

In[15]:=
hamlet = ExampleData[{"Text", "Hamlet"}];
hamlet = ResourceFunction["CaesarCipher"][hamlet, 6];
ResourceFunction["CrackCaesarCipher"][hamlet] // Short
Out[16]=

Properties and Relations

The function CrackCaesarCipher can, like CaesarDecipher, undo a encipherment done by CaesarCipher:

In[17]:=
message = ResourceFunction["CaesarCipher"]["This is a test", 6];
{ResourceFunction["CaesarDecipher"][message, 6], ResourceFunction["CrackCaesarCipher"][message]}
Out[18]=

Possible Issues

The setting for Language can change the outcome:

In[19]:=
message = ResourceFunction["CaesarCipher"]["De rode auto!", 11];
ResourceFunction["CrackCaesarCipher"][message, Method -> "Dictionary",
    Language -> #] & /@ {"Finnish", "Dutch"}
Out[20]=

The deciphered message with the highest score might not be the right one, in this case the second highest is the right deciphered message:

In[21]:=
message = ResourceFunction["CaesarCipher"]["The voodoo xeroxed a puppy", 11];
ResourceFunction["CrackCaesarCipher"][message, 10, Method -> "LetterFrequency"] // Dataset
Out[22]=

Long strings take very long to decipher using the Method “Dictionary”:

In[23]:=
shorthamlet = StringTake[ExampleData[{"Text", "Hamlet"}], 1000];
shorthamlet = ResourceFunction["CaesarCipher"][shorthamlet, 6];
AbsoluteTiming[
 ResourceFunction["CrackCaesarCipher"][shorthamlet, Method -> "Dictionary"];]
Out[24]=

A frequency analysis is much faster:

In[25]:=
AbsoluteTiming[
 ResourceFunction["CrackCaesarCipher"][shorthamlet, Method -> "LetterFrequency"];]
Out[25]=

Resource History

See Also

License Information