Created
March 24, 2018 14:25
-
-
Save randomnerd/7758c41d588acb4675acee656756630c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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