Skip to content

Instantly share code, notes, and snippets.

@alexjohnj
Created April 19, 2014 21:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexjohnj/11098550 to your computer and use it in GitHub Desktop.
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.
// 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