Senior
Condition We have a database of user passwords, which are hashed (using the hashPassword function), and we also know the set of characters that can be used in passwords (the variable alphabet). Our task is to implement the RecoverPassword function so that it recovers the password from the known hash and TestRecoverPassword completes successfully. Basic requirements: Solve as you wish package main import ( "crypto/md5" "fmt" ) var alphabet = []rune{'a', 'b', 'c', 'd', '1', '2', '3'} func RecoverPassword(h []byte) string { return "" } func hashPassword(in string) []byte { h := md5.Sum([]byte(in)) return h[:] } func main() { tests := []string{"a", "12", "abc333d"} ok := true for _, exp := range tests { h := hashPassword(exp) act := RecoverPassword(h) if act != exp { fmt.Printf("Error: expected %q, got %q\n", exp, act) ok = false } } if ok { fmt.Println("All tests passed successfully") } }
sobes.tech AI
Answer from AI
Task — recover the original password from a known MD5 hash using a given alphabet. Since MD5 is a one-way function, the only practical way is to brute-force all possible combinations from the alphabet until a match is found.
Implementation:
- Iterate over passwords of different lengths (for example, from 1 to some maximum).
- For each length, generate all possible strings from the alphabet.
- For each string, compute its MD5 hash and compare it with the given hash.
- If it matches, return the found password.
Example code in Go:
package main
import (
"crypto/md5"
"fmt"
)
var alphabet = []rune{'a', 'b', 'c', 'd', '1', '2', '3'}
func hashPassword(in string) []byte {
h := md5.Sum([]byte(in))
return h[:]
}
func RecoverPassword(h []byte) string {
maxLen := 7 // maximum password length (as per test condition)
var helper func(pos int, current []rune) string
helper = func(pos int, current []rune) string {
if pos == len(current) {
if string(current) != "" && equalSlices(hashPassword(string(current)), h) {
return string(current)
}
return ""
}
for _, c := range alphabet {
current[pos] = c
res := helper(pos+1, current)
if res != "" {
return res
}
}
return ""
}
for length := 1; length <= maxLen; length++ {
res := helper(0, make([]rune, length))
if res != "" {
return res
}
}
return ""
}
func equalSlices(a, b []byte) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
func main() {
tests := []string{"a", "12", "abc333d"}
ok := true
for _, exp := range tests {
h := hashPassword(exp)
act := RecoverPassword(h)
if act != exp {
fmt.Printf("Error: expected %q, got %q\n", exp, act)
ok = false
}
}
if ok {
fmt.Println("All tests passed successfully")
}
}
This code brute-forces all password options of length from 1 to 7 from the given alphabet and compares their hash with the provided one. When a match is found, it returns the password.
Note: such brute-force works only with a small alphabet size and limited password length, otherwise, the execution time will grow exponentially.