Sobes.tech
Senior

შობა ჩვენ გვაქვს მომხმარებლების პაროლების ბაზა, პაროლები ჰეშირებულია (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("ყველა ტესტი წარმატებით ჩატარდა") } }

sobes.tech AI

პასუხი 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 символов из заданного алфавита и сравнивает их хэш с заданным. При совпадении возвращает найденный пароль.

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