Sobes.tech
Senior

We have a database with user passwords, passwords are hashed (hashPassword function), and a set of characters that can be used in passwords (variable alphabet). Our task is to implement the RecoverPassword function so that it recovers the password by 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() {

sobes.tech AI

Answer from AI

To recover a password from a known MD5 hash and a given alphabet, you need to try all possible combinations of characters from the alphabet, compute their hash, and compare it with the given one. When a match is found, return the password.

An example implementation with brute-force for passwords of length from 1 up to some maximum (for example, 5):

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 := 5
    var attempt func(pos int, current []rune) string

    attempt = func(pos int, current []rune) string {
        if pos == 0 {
            // Check the current combination
            candidate := string(current)
            if string(hashPassword(candidate)) == string(h) {
                return candidate
            }
            return ""
        }
        for _, ch := range alphabet {
            current[len(current)-pos] = ch
            res := attempt(pos-1, current)
            if res != "" {
                return res
            }
        }
        return ""
    }

    for length := 1; length <= maxLen; length++ {
        current := make([]rune, length)
        res := attempt(length, current)
        if res != "" {
            return res
        }
    }
    return ""
}

func main() {
    password := "abc1"
    h := hashPassword(password)
    recovered := RecoverPassword(h)
    fmt.Printf("Original: %s, Recovered: %s\n", password, recovered)
}

This code tries all possible passwords of length up to 5 from the given alphabet, computes their MD5 hash, and compares it with the target hash. When a match is found, it returns the password.

Note that such brute-force search can be very time-consuming with a large alphabet and password length.