Senior
Condition Nous avons une base de données avec les mots de passe des utilisateurs, les mots de passe sont hachés (fonction hashPassword), et nous connaissons également l'ensemble des caractères pouvant être utilisés dans les mots de passe (variable alphabet). Notre tâche est d'implémenter la fonction RecoverPassword pour qu'elle restaure le mot de passe à partir du hash connu et que TestRecoverPassword se termine avec succès. Exigences de base: N'importe quelle méthode est acceptable 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("Erreur : attendu %q, obtenu %q\n", exp, act) ok = false } } if ok { fmt.Println("Tous les tests ont réussi") } }
sobes.tech IA
Réponse de l'IA
Задача — по известному 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 символов из заданного алфавита и сравнивает их хэш с заданным. При совпадении возвращает найденный пароль.
Важно: такой перебор работает только при небольшом размере алфавита и ограниченной длине пароля, иначе время выполнения будет экспоненциально расти.