花密 C 语言核心代码

准备工作

下载依赖库:spaniakos 的 ArduinoMD5

选择这个库的原因是代码可以在 Arduino 或 Raspberry Pi 上运行。

头文件包含

拷贝三个文件:MD5_config.hMD5.hMD5.cpp 到项目文件夹,并在源代码文件中包含:

1
#include "MD5.h"

核心代码

JavaScript的isNaN()函数C语言实现:

1
2
3
4
5
6
7
char isNaN(char ch) {
if ('0' <= ch && ch <= '9') {
return 0;
} else {
return 1;
}
}

字母字符转大写:

1
2
3
4
5
6
char toupper(char c) {
if (('a' <= c) && (c <= 'z')) {
c = c - ('a' - 'A');
}
return c;
}

花密计算核心代码:

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
char fpCode(const char* password, char* key, char code[33], unsigned char length) {
unsigned char pwdLen = strlen(password);
unsigned char keyLen = strlen(key);

if ((1 > pwdLen) || (1 > keyLen) || (1u > length) || (length > 32u)) {
return 0;
}

MD5 hashMD5;

char* pHmd5 = hashMD5.hmac_md5(password, pwdLen, key, keyLen);
char hmd5[32];
memcpy(hmd5, pHmd5, 32);

char* pKise = "kise";
char* pRule = hashMD5.hmac_md5(hmd5, 32, pKise, 4);
char rule[32];
memcpy(rule, pRule, 32);

char* pSnow = "snow";
char* pSource = hashMD5.hmac_md5(hmd5, 32, pSnow, 4);
char source[32];
memcpy(source, pSource, 32);

for (unsigned char i = 0; i < 32; i++) {
if (isNaN(source[i])) {
if (strchr("sunlovesnow1990090127xykab", rule[i]) != NULL) {
source[i] = toupper(source[i]);
}
}
}

if (isNaN(source[0]) == 0) {
source[0] = 'K';
}

memset(code, 0, 33);
memcpy(code, source, sizeof(char) * length);

return 1;
}

使用方法

生成 code[] 的数组为什么不是32,而是33?

是为了输出字符串结果,特意多加了一个 '\0' 位。

1
2
3
4
5
6
7
8
9
char* p = "password";
char* k = "key";
char c[33];

if (fpCode(p, k, c, 16) == 1) {
printf("fpCode=%s", c);
} else {
printf("Error!");
}