Назад к вопросам
Ozon Финтех
Senior
10
Условие У нас есть база данных с паролями пользователей, пароли захешированы (функция 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 range tests { h := hashPassword(exp) act := RecoverPassword(h) if act != exp { fmt.Printf("Ошибка: ожидалось %q, получено %q\n", exp, act) ok = false } } if ok { fmt.Println("Все тесты пройдены успешно") } }
Компании, где спрашивали
Ответ от нейросети
sobes.tech 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 символов из заданного алфавита и сравнивает их хэш с заданным. При совпадении возвращает найденный пароль.
Важно: такой перебор работает только при небольшом размере алфавита и ограниченной длине пароля, иначе время выполнения будет экспоненциально расти.