Sobes.tech
Senior

Bedingung Wir haben eine Datenbank mit Benutzerpasswörtern, die Passwörter sind gehasht (Funktion hashPassword), und es ist auch bekannt, welche Zeichen in den Passwörtern verwendet werden können (Variable alphabet). Unsere Aufgabe ist es, die Funktion RecoverPassword zu implementieren, damit sie das Passwort anhand des bekannten Hashes wiederherstellt und TestRecoverPassword erfolgreich abgeschlossen wird. Grundlegende Anforderungen: Jede Methode ist erlaubt 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("Fehler: erwartet %q, erhalten %q\n", exp, act) ok = false } } if ok { fmt.Println("Alle Tests erfolgreich bestanden") } }

sobes.tech KI

Antwort von AI

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

Реализация:

  • Перебираем пароли разной длины (например, от 1 до некоторого максимума).
  • Для каждой длины генерируем все возможные строки из alphabet.
  • Для каждой строки считаем MD5 и сравниваем с заданным хэшем.
  • Если совпало — возвращаем найденный пароль.

Пример кода на 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 // максимальная длина пароля (по условию теста)
    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("Ошибка: ожидалось %q, получено %q\n", exp, act)
            ok = false
        }
    }
    if ok {
        fmt.Println("Все тесты пройдены успешно")
    }
}

Этот код перебирает все варианты паролей длиной от 1 до 7 символов из заданного алфавита и сравнивает их хэш с заданным. При совпадении возвращает найденный пароль.

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