It's Go Time - Observations, a simple "password" cracker, speed, and some example code in Golang

TL;DR

I wrote a little password cracker proof of concept in Python and Go. The Go code was about twice as fast as the Python code. Go seems bad ass.

Summary

I'm currently on a plane and the Internet is spotty/nonexistant, so before I took off I downloaded a bunch of Go documentation and started learning the language. I read the first few pages of a really awesome Go PDF and decided to slap together a quick password cracking proof of concept.

I wrote some Go code that brute forces an MD5 hash for a number between one and ninety-nine million. For comparison, I wrote something that does functionally the exact same thing in Python. While I know this isn't exactly what people mean by "fast", I've heard that Go was pretty quick so I expected it to outperform Python. I didn't optimize any of the code whatsoever in either versions. This was simply meant to be a quick and dirty example. It was a fun piece of code to write but I don't think I'll be replacing Hashcat anytime soon.

I'd also like to note that this is literally the first Go code I've ever written, so please feel free to provide any feedback on my code style. I'm still an extremely novice programmer so I'm always happy to receive constructive critisism.

Go

// apparently I always need this
package main

// import all the libraries I'll need
import (  
    "fmt"
    "os"
    "crypto/md5"
    "encoding/hex"
    "strconv"
)

// define a string variable "cipher" from the first command line arg
var cipher string = os.Args[1]         

func main() {  
    // give a heads up that we're starting
    fmt.Println("[+] Cracking...")
    // C-style for loop
    for i := 1; i < 99999999; i++ {
        // use strconv to convert integer to string, 
        // hash the string, then compare it to our provided hash
        if GetMD5Hash(strconv.Itoa(i)) == cipher { 
            // if we get a match, print it out and exit with a zero exit code
            fmt.Printf("[!] The code has been cracked: %d\n", i)
            os.Exit(0)
        }
    }
}

// function that takes a string and returns the md5 of that string
func GetMD5Hash(text string) string {  
    hasher := md5.New()
    hasher.Write([]byte(text))
    return hex.EncodeToString(hasher.Sum(nil))
}

Python

This is way less cool. Python seems sort of boring in general after a few minutes of exposure to Go.

#!/usr/bin/env python

import hashlib  
import sys

cipher = sys.argv[1]

print "[+] Cracking..."

for n in range(1, 99999999):  
    if hashlib.md5(str(n)).hexdigest() == cipher:
        print "[!] The code has been cracked: %d" % n
        exit()

If you want to try it out yourself, you can generate an MD5 of a random number with the following Bash + Python one-liner:

$ python -c "import hashlib; import random; print hashlib.md5(str(random.randint(10000000,99999999))).hexdigest()"

Results

As expected, Go outperformed Python. Depending on the number, Go was typically between 1.5 to 2.0 times as fast.

$ time ./crack 45f02a94cf0e1590e9266f3820fe5779
[+] Cracking...
[!] The code has been cracked: 63158652

real    0m58.904s  
user    0m59.167s  
sys    0m3.660s

$ time python crack.py 45f02a94cf0e1590e9266f3820fe5779
[+] Cracking...
[!] The code has been cracked: 63158652

real    1m45.235s  
user    1m43.695s  
sys    0m1.412s  

This particular example doesn't really mean much, since Python doesn't really start to get slow until you start adding a lot of lines of code and libraries.

Conclusion

Go seems awesome, especially for such a young and hipster programming language. I'd like to going to start building things in Go instead of Python at work for anything other than rapid prototypes. I'd really like to become as adept at Go as I am with Python. I also think using Go will force me to become a better programmer, since you really can't get away with a lot of the same bullshit in Go as you can get away with in Python.

I remember encountering Python for the first time years ago and thinking to myself "wow, this language is really cool. I should pick it up". Then I didn't actually pick it up until about 2013 and I really regret it. I don't want to make that same mistake with Go, which is why I'd like to start learning it early.

I checked the code into Github if anyone wants to check it out there. As always, please don't hesitate to contact me directly if you have any questions or feedback.

Thanks!

--Andrew

"Find what you love and let it kill you"