6
\$\begingroup\$

I'm learning Go at this moment and it is my first program in Go, so I will be thankfull for any suggestion, remarks and observations.

package main
import (
 "fmt"
)
const ascii = "abcdefghijklmnopqrstuvwxyz"
var goodness_values = []float32 { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
func zip(s1 string, s2 string) map[string]string {
 result := make(map[string] string)
 for i, v := range s1 {
 result[string(v)] = string(s2[i])
 }
 return result
}
func crypt(s string, table map[string]string) string {
 result := ""
 for _, v := range s {
 result += table[string(v)] 
 }
 return result
}
func encode(message string, key int) string {
 shifted_ascii := ascii[key:] + ascii[:key]
 trans_table := zip(ascii, shifted_ascii)
 return crypt(message, trans_table)
}
func decode(secret string, key int) string {
 shifted_ascii := ascii[key:] + ascii[:key]
 trans_table := zip(shifted_ascii, ascii)
 return crypt(secret, trans_table)
}
func goodness(version string, letter_goodness map[string] float32) float32 {
 var result float32 = 0.0
 for _, v := range version {
 result += letter_goodness[string(v)]
 }
 return result
}
func crack(secret string) string {
 var best_score float32 = 0.0
 result := ""
 letter_goodness := make(map[string] float32)
 for i, v := range ascii {
 letter_goodness[string(v)] = goodness_values[i]
 }
 for i := 0; i <= 26; i++ { 
 version := decode(secret, i);
 score := goodness(version, letter_goodness);
 if(score > best_score) {
 best_score = score
 result = version
 }
 }
 return result
}
func main() {
 fmt.Printf("%s\n", encode("hello", 10))
 fmt.Printf("%s\n", decode("rovvy", 10))
 fmt.Printf("%s\n", crack("pybrscpexnkwoxdkvmyxdbsledsyxcdydronopsxsdsyxkxnnocsqxypzbyqbkwwsxqvkxqekqoc"))
}
Vogel612
25.5k7 gold badges59 silver badges141 bronze badges
asked Oct 30, 2012 at 12:57
\$\endgroup\$
1
  • \$\begingroup\$ This question is on-topic, it is " concrete code from a project, with sufficient context for reviewers to understand how that code is used" . This is not Pseudocode, stub code, hypothetical code or obfuscated code. \$\endgroup\$ Commented Jun 6, 2018 at 21:37

1 Answer 1

3
\$\begingroup\$

It looks like it was written in another language and then translated to Go. It looks complicated. Go is designed to be efficient. Maps are not as efficient as slices and arrays for simple indexing. decode(secret, i) executes 26 times instead of once. Etc.

Here's an alternate version,

package main
import "fmt"
const alphabet = "abcdefghijklmnopqrstuvwxyz"
func rotate(s string, rot int) string {
 rot %= 26
 b := []byte(s)
 for i, c := range b {
 c |= 0x20
 if 'a' <= c && c <= 'z' {
 b[i] = alphabet[(int(('z'-'a'+1)+(c-'a'))+rot)%26]
 }
 }
 return string(b)
}
func decode(cipher string, rot int) (text string) {
 return rotate(cipher, -rot)
}
func encode(text string, rot int) (cipher string) {
 return rotate(text, rot)
}
var frequencies = []float32{
 .0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241,
 .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007,
}
func crack(cipher string) (text string) {
 var sums [26]float32
 for _, c := range cipher {
 c |= 0x20
 for j := range sums {
 if 'a' <= c && c <= 'z' {
 sums[j] += frequencies[(int(c)-int('a')+j)%26]
 }
 }
 }
 var maxi, maxsum = 0, float32(0)
 for i, sum := range sums {
 if sum > maxsum {
 maxsum = sum
 maxi = i
 }
 }
 return rotate(cipher, maxi)
}
func main() {
 fmt.Printf("%s\n", encode("hello", 10))
 fmt.Printf("%s\n", decode("rovvy", 10))
 fmt.Printf("%s\n", crack("pybrscpexnkwoxdkvmyxdbsledsyxcdydronopsxsdsyxkxnnocsqxypzbyqbkwwsxqvkxqekqoc"))
}

Output:

rovvy
hello
forhisfundamentalcontributionstothedefinitionanddesignofprogramminglanguages
answered Oct 31, 2012 at 3:18
\$\endgroup\$
3
  • \$\begingroup\$ Thank you very much for your help. Expression '('z'-'a'+1)+' as I see can be removed from code ? Am I right ? \$\endgroup\$ Commented Oct 31, 2012 at 9:53
  • \$\begingroup\$ And another one question: what is 'c |= 0x20' ? \$\endgroup\$ Commented Oct 31, 2012 at 9:54
  • 2
    \$\begingroup\$ | is the bitwise-or operator, |= in turn ORs the lhs with the rhs and assigns it to the lhs. ORing an ASCII character with 0x20 has the effect of converting uppercase to lowercase (and leaving numbers and symbols untouched). \$\endgroup\$ Commented Nov 12, 2012 at 7:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.