字符串生成md5码

Posted by Kalos Aner on October 25, 2025

引言

今天看了一篇数据安全相关的文章,联想到在做练习时一些密码数据都是使用 MD5 加密之后的密钥来存储的。突发奇想如果银行中用户的支付密码的数据也只用简单的 MD5 加密的话,考虑到支付密码只有 6 位,组合一共才 1E6 可能性。这时如果我直接枚举所有的可能性然后生成对应的 MD5 码并且使用哈希表来存储,这样我就可以通过对应的 MD5 码来直接查到密码原文。就算有可能多个密码会生成同一个 MD5 码,这种可能性也不是很大,最终也能找到几个候选的原文密码。

当然以上只是我的幻想,实际上银行存储密码的方式肯定比这种方式复杂得多。而且即便追求简单也可以使用另外一种方法来存储密码:连续求两次 MD5 码,这样即便是想暴力破解也没那么容易了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <openssl/md5.h>
#include <unordered_map>
#include <vector>
#include <sstream>
#include <iomanip>

using namespace std;

const int N = 1000000;

string gen_str(int x) {
    string res = "000000";
    for (int i = res.size() - 1; i >= 0 && x > 0; -- i) {
        res[i] = x % 10 + '0';
        x /= 10;
    }
    return res;
}

string gen_md5(string x) {
    vector<unsigned char> res(MD5_DIGEST_LENGTH);
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, x.c_str(), x.size());
    MD5_Final(res.data(), &ctx);
    stringstream ss;
    for (unsigned char byte : res) {
        ss << hex << setw(2) << setfill('0') << (int)byte;
    }
    return ss.str();
}

int main() {
    unordered_map<string, vector<string>> hash_table;
    for (int i = 0; i < N; ++ i) {
        string s = gen_str(i);
        string x = gen_md5(s);
        // cout << s << " | " << x << endl;
        hash_table[x].push_back(s);
    }
    string s;
    do {
        cout << "input md5 of password: " << endl;
        cin >> s;
        cout << "It's password maybe is :" << endl;
        for (string s : hash_table[s]) {
            cout << s << endl;
        }
        cout << endl;
    } while (s != "over");
}

编译:g++ xxx.cpp -o xxx -lcrypto