diff options
-rw-r--r-- | main.go | 73 | ||||
-rw-r--r-- | structs/structs.go | 105 |
2 files changed, 178 insertions, 0 deletions
diff --git a/main.go b/main.go new file mode 100644 index 0000000..13a1844 --- /dev/null +++ b/main.go @@ -0,0 +1,73 @@ +package main + +import ( + "bufio" + "fmt" + "git.darknebu.la/emile/Substitution-Cracker/structs" + "os" +) + +/* + Goal: Make Chaining ok + + 1. Pack the original String into a channel + 2. Use one of the methods to decrypt (convert type (ascii, dec, hex, bin, ...), base64, rot-n, ...) + 3. Check (letter freq, n-grams, ...) + 4. if not final, goto 2 +*/ + +func main() { + // Get the Ciphertext input + var ciphertext structs.Ciphertext = getCipherText() + mainChannel := make(chan structs.Ciphertext, 100) + + ciphertext.DecodeRotN(mainChannel) + FrequencyAnalysisOnChannel(mainChannel) + BiGramAnalysisOnChannel(mainChannel) + + // Get all elements from the Channel and print them + mainChannelLength := len(mainChannel) + for i := 0; i < mainChannelLength; i++ { + (<-mainChannel).Println() + } +} + +// Read from ST +func getCipherText() structs.Ciphertext { + reader := bufio.NewReader(os.Stdin) + fmt.Print("Enter ciphertext: ") + text, _ := reader.ReadString('\n') + return structs.Ciphertext{Text: text} +} + +// Run a Frequency Analysis on all Elements inside a given channel +func FrequencyAnalysisOnChannel(mainChannel chan structs.Ciphertext) { + + // Generate a FrequencyMap + mainChannelLength := len(mainChannel) + for i := 0; i < mainChannelLength; i++ { + (<-mainChannel).GenFrequencyMap(mainChannel) + } + + // Analyze the FrequencyMap + //mainChannelLength = len(mainChannel) + //for i := 0; i < mainChannelLength; i++ { + // (<- mainChannel).AnalyzeFrequencyMap(mainChannel) + //} +} + +// Run a BiGramAnalysis on all Elements inside a given channel +func BiGramAnalysisOnChannel(mainChannel chan structs.Ciphertext) { + + // Generate a BiGramMap + mainChannelLength := len(mainChannel) + for i := 0; i < mainChannelLength; i++ { + (<-mainChannel).GenBiGramMap(mainChannel) + } + + // Analyze the BiGramMap + //mainChannelLength = len(mainChannel) + //for i := 0; i < mainChannelLength; i++ { + // (<- mainChannel).AnalyzeBiGramMap(mainChannel) + //} +} diff --git a/structs/structs.go b/structs/structs.go new file mode 100644 index 0000000..9f12b34 --- /dev/null +++ b/structs/structs.go @@ -0,0 +1,105 @@ +package structs + +import ( + "fmt" +) + +type Ciphertext struct { + Text string // the CipherText + FrequencyMap map[string]int // frequency map + BiGrams map[string]int // frequency map + cipher []string // list of ciphers that were applied to get this payload +} + +// RotAll rotates the given ciphertext for all possile rotations +func (CiphertextVar Ciphertext) DecodeRotN(mainChannel chan Ciphertext) { + + // Calculate the new ciphertext for all rotations and push the result into the channel + for i := 0; i < 26; i++ { + CiphertextVar.Rot(i, mainChannel) + } +} + +// Rot rotates a ciphertext n units in one direction +func (CiphertextVar Ciphertext) Rot(n int, mainChannel chan Ciphertext) { + + // Length of the given ciphertext + var CiphertextLength int = len(CiphertextVar.Text) + var RotatedText string + + // Iterate over all the chars in the ciphertext and shift them by i units circular + for i := 0; i < CiphertextLength; i++ { + + // Handle uppercase characters + if 65 < int(CiphertextVar.Text[i]) == true && (int(CiphertextVar.Text[i])) < 90 == true { + var newChar = (((int(CiphertextVar.Text[i]) + n) - 65) % 26) + 65 + RotatedText += string(newChar) + } + + // Handle lowercase characters + if 97 < int(CiphertextVar.Text[i]) == true && (int(CiphertextVar.Text[i])) < 122 == true { + var newChar = (((int(CiphertextVar.Text[i]) + n) - 97) % 26) + 97 + RotatedText += string(newChar) + } + } + + // Convert the RotatedText string into a Ciphertext struct + RotatedCipherStruct := Ciphertext{ + Text: RotatedText, + FrequencyMap: nil, + cipher: nil, + } + + // Push the RotatedCipherStruct back into the main channel + mainChannel <- RotatedCipherStruct +} + +func (PrintString Ciphertext) Println() { + fmt.Println(PrintString) +} + +func (CiphertextVar Ciphertext) GenFrequencyMap(mainChannel chan Ciphertext) { + + // Initialize a Map mapping runes (chars) to ins (the amount of occurrences) + newFrequencyMap := make(map[string]int) + + // Iterate over all the characters in the CipherText generating a FrequencyMap + CipherTextLength := len(CiphertextVar.Text) + ciphertext := CiphertextVar.Text + for i := 0; i < CipherTextLength; i++ { + newFrequencyMap[string(rune(ciphertext[i]))] = newFrequencyMap[string(rune(ciphertext[i]))] + 1 + } + + // Generate an instance of the Ciphertext containing the new FrequencyMap + newCipherText := Ciphertext{ + Text: CiphertextVar.Text, + FrequencyMap: newFrequencyMap, + BiGrams: nil, + cipher: nil, + } + + // Push the newCipherText back into the mainChannel + mainChannel <- newCipherText +} + +func (CiphertextVar Ciphertext) GenBiGramMap(mainChannel chan Ciphertext) { + newBiGramMap := make(map[string]int) + + // Iterate over all the characters in the CipherText generating a FrequencyMap + CipherTextLength := len(CiphertextVar.Text) + ciphertext := CiphertextVar.Text + for i := 0; i < CipherTextLength-1; i++ { + newBiGramMap[string(ciphertext[i:i+2])] = newBiGramMap[string(ciphertext[i:i+2])] + 1 + } + + // Generate an instance of the Ciphertext containing the new FrequencyMap + newCipherText := Ciphertext{ + Text: CiphertextVar.Text, + FrequencyMap: CiphertextVar.FrequencyMap, + BiGrams: newBiGramMap, + cipher: nil, + } + + // Push the newCipherText back into the mainChannel + mainChannel <- newCipherText +} |