Sobes.tech
Senior

Koşul Kullanıcı şifreleriyle bir veritabanımız var, şifreler hashlenmiş (hashPassword fonksiyonu), ve ayrıca şifrelerde kullanılabilecek karakterler kümesi biliniyor (değişken alphabet). Amacımız, bilinen hash'e göre şifreyi geri kazanacak RecoverPassword fonksiyonunu uygulamaktır ve TestRecoverPassword başarılı olmalıdır. Temel gereksinimler: Herhangi bir yöntem kullanılabilir 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("Hata: beklenen %q, alınan %q\n", exp, act) ok = false } } if ok { fmt.Println("Tüm testler başarıyla geçti") } }

sobes.tech yapay zeka

AI'dan gelen yanıt

Задача — по известному 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 символов из заданного алфавита и сравнивает их хэш с заданным. При совпадении возвращает найденный пароль.

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