Sobes.tech
Back to questions
Middle+
11

У нас есть база данных с паролями пользователей, пароли захешированы (функция hashPassword), а так же известен набор символов которые могут быть использованы в паролях (переменная alphabet). Наша задача реализовать функцию RecoverPassword так, чтобы она восстанавливала пароль по известному хэшу и TestRecoverPassword завершился успешно Базовые требования: Решить как угодно 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("Ошибка: ожидалось %q, получено %q\n", exp, act) ok = false } } if ok { fmt.Println("Тесты пройдены успешно") } }

Companies where asked
OZONOZON

Answer from AI

sobes.tech AI

Задача — по известному MD5-хэшу и алфавиту восстановить исходный пароль. Поскольку MD5 — хеш-функция, обратного преобразования нет, но можно перебрать все возможные комбинации из alphabet и сравнить их хэш с заданным.

Для успешного прохождения тестов нужно реализовать перебор паролей с длиной от 1 до максимальной длины тестовых паролей (например, до 7 символов).

Пример решения с рекурсивным перебором:

func RecoverPassword(h []byte) string {
    var result string
    var found bool

    var dfs func(current []rune)
    dfs = func(current []rune) {
        if found {
            return
        }
        if len(current) > 0 {
            if stringHash := hashPassword(string(current)); stringHash != nil && stringEqual(stringHash, h) {
                result = string(current)
                found = true
                return
            }
        }
        if len(current) == 7 { // максимальная длина из тестов
            return
        }
        for _, c := range alphabet {
            dfs(append(current, c))
        }
    }

    dfs([]rune{})
    return result
}

func stringEqual(a, b []byte) bool {
    if len(a) != len(b) {
        return false
    }
    for i := range a {
        if a[i] != b[i] {
            return false
        }
    }
    return true
}

Такой перебор гарантирует нахождение пароля из заданного алфавита и длины до 7 символов. В реальных условиях перебор может быть дорогим, но для теста и ограниченного алфавита подходит.