Created
April 19, 2014 21:50
-
-
Save alexjohnj/11098550 to your computer and use it in GitHub Desktop.
A program that performs a very basic frequency analysis on a string encrypted with a Caesar cipher.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// vici performs a very basic frequency analysis on a string of text encrypted with a Caesar cipher. | |
// It will output all possible keys and plaintexts for the ciphertext, with the most likely key/plaintext first and the least likely last | |
// Usage: vici [ciphertext] | |
// **NOTE** You'll need to run `go get github.com/alexjohnj/caesar` to build this program | |
// **NOTE 2** Since this outputs 26 lines of text to the console, you might want to redirect the output to a file. | |
package main | |
import ( | |
"bytes" | |
"fmt" | |
"github.com/alexjohnj/caesar" | |
"log" | |
"os" | |
) | |
func main() { | |
frequencyMap := make(map[byte]int) | |
// Source for letter frequency: http://en.wikipedia.org/wiki/Letter_frequency#Relative_frequencies_of_letters_in_the_English_language | |
englishFrequencyList := []byte{'e', 't', 'a', 'o', 'i', 'n', 's', 'h', 'r', 'd', 'l', 'c', 'u', 'm', 'w', 'f', 'g', 'y', 'p', 'b', 'v', 'k', 'j', 'x', 'q', 'z'} | |
if len(os.Args) != 2 { | |
log.Fatal("Incorrect number of arguments") | |
} | |
ciphertext := bytes.ToLower([]byte(os.Args[1])) | |
// Find the frequency of each letter in the ciphertext | |
for _, byteVal := range ciphertext { | |
if byteVal >= 'a' && byteVal <= 'z' { | |
frequencyMap[byteVal] += 1 | |
} | |
} | |
// Get the most frequent letter | |
var mostFrequentLetter byte | |
biggestFrequency := 0 | |
for key, value := range frequencyMap { | |
if value > biggestFrequency { | |
biggestFrequency = value | |
mostFrequentLetter = key | |
} | |
} | |
// Determine the most probable keys based on the frequency of letters in the English alphabet | |
for _, letter := range englishFrequencyList { | |
potentialKey := (26 + (mostFrequentLetter - letter)) % 26 | |
potentialPlaintext := caesar.DecryptCiphertext(string(ciphertext), int(potentialKey)) | |
fmt.Printf("Potential Key: %d\tPotential Plaintext: %s\n", potentialKey, potentialPlaintext) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment