Skip to content

Instantly share code, notes, and snippets.

@randomnerd
Created March 24, 2018 14:25
Show Gist options
  • Save randomnerd/7758c41d588acb4675acee656756630c to your computer and use it in GitHub Desktop.
Save randomnerd/7758c41d588acb4675acee656756630c to your computer and use it in GitHub Desktop.
package main
import (
"crypto/md5"
"encoding/hex"
"flag"
"fmt"
"math"
"math/rand"
"time"
)
func main() {
// init params
start := flag.Int("start", 1, "starting value")
stop := flag.Int("stop", 32, "stop value")
if *stop < *start {
panic("stop cant be less than start")
}
flen := flag.Int("len", 6, "number of digits after point")
tryguess := flag.Bool("guess", false, "should the program try to bruteforce the hash")
flag.Parse()
// init random generator
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
// generate a number to guess
num := *start + r1.Intn(*stop-*start)
// generate floating part to prevent cheating
fnum := r1.Uint64()
// get resulting string and md5sum of it
str := fmtstr(num, *flen, fnum)
mstr := md5sum(str)
fmt.Println("magic:", str)
fmt.Println("md5:", mstr)
if *tryguess {
fmt.Println("trying to guess the number with bruteforce...")
timer := time.Now()
guess := bforce(*start, *stop, *flen, mstr)
fmt.Println("guessed number:", guess, "| time spent to guess:", time.Since(timer))
}
}
func md5sum(s string) string {
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}
func fmtstr(num, flen int, fnum uint64) string {
// pad uint if it happens to be shorter than required length
padfmt := fmt.Sprintf("%%0%dd", flen)
padstr := fmt.Sprintf(padfmt, fnum)
// or truncate it if it happens to be longer that required
strfmt := fmt.Sprintf("%%d.%%.%ds", flen)
return fmt.Sprintf(strfmt, num, padstr)
}
func bforce(start, stop, flen int, hash string) int {
var num int
// open channel to receive results from loops when they finish and close it when we're done
ch := make(chan int)
defer close(ch)
// open a thread for each number it could be and loop through the floating point part
for num = start; num <= stop; num++ {
go fmtstrloop(num, flen, hash, ch)
}
// receive results from loop functions
// it returns -1 if the number was not correct, or the number itself it guess succeeded
for num = start; num <= stop; num++ {
ret := <-ch
if ret != -1 {
return ret
}
}
// should never happen unless input data is wrong
return -1
}
func fmtstrloop(num, flen int, hash string, ch chan<- int) {
var fnum, max uint64
// get max number we should count to
max = uint64(math.Pow10(flen))
// loop thru the numbers and compare their md5sum with the hash provided
for fnum = 0; fnum < max; fnum++ {
str := md5sum(fmtstr(num, flen, fnum))
if str == hash {
ch <- num
}
}
ch <- -1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment