Senior
Nosacījums Mums ir lietotāju paroles datu bāze, paroles ir hashētas (hashPassword funkcija), un arī ir zināms rakstzīmju kopums, ko var izmantot paroles (mainīgais alphabet). Mūsu uzdevums ir īstenot funkciju RecoverPassword tā, lai tā atgūtu paroli pēc zināmā haša un TestRecoverPassword veiksmīgi noslēgtos. Pamatprasības: Jebkura metode ir atļauta 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("Kļūda: gaidīts %q, saņemts %q\n", exp, act) ok = false } } if ok { fmt.Println("Visi testi veiksmīgi izpildīti") } }
sobes.tech AI
Atbilde no 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 символов из заданного алфавита и сравнивает их хэш с заданным. При совпадении возвращает найденный пароль.
Важно: такой перебор работает только при небольшом размере алфавита и ограниченной длине пароля, иначе время выполнения будет экспоненциально расти.