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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
#include "hash.h"
#include "crc32.h"
#include <stdexcept>
namespace Hex {
static char* digits = "0123456789abcdef";
std::string hex(char* bin, int length) {
std::string s(length * 2, ' ');
for(int i = 0; i < length; i++) {
s[i*2] = digits[(bin[i] >> 4) & 0xf];
s[i*2+1] = digits[bin[i] & 0xf];
}
return s;
}
std::string hex(int bin) {
std::string s(sizeof(int) * 2, ' ');
for(int i = 0; i < sizeof(int) * 2; i++) {
s[sizeof(int) * 2 - 1 - i] = digits[bin & 0xf];
bin = bin >> 4;
}
return s;
}
}
Hash::Hash() {
finished = false;
crc32_ctx = 0;
crc32_str = "";
ed2k_str = "";
MD5_Init(&md5_ctx);
md5_str = "";
SHA1_Init(&sha1_ctx);
sha1_str = "";
}
void Hash::update(std::string data) {
if(finished) {
throw std::runtime_error("Can't update after digest.");
}
crc32_ctx = CRC32::crc32(crc32_ctx, data.c_str(), data.length());
ed2k_ctx.update(data.c_str(), data.length());
MD5_Update(&md5_ctx, data.c_str(), data.length());
SHA1_Update(&sha1_ctx, data.c_str(), data.length());
}
std::string Hash::crc32() {
return Hex::hex(crc32_ctx);
}
std::string Hash::ed2k() {
if(!ed2k_str.length()) {
finished = true;
char* digest = ed2k_ctx.digest();
ed2k_str = Hex::hex(digest, 16);
delete digest;
}
return ed2k_str;
}
std::string Hash::md5() {
if(!md5_str.length()) {
finished = true;
char* digest = new char[16];
MD5_Final((unsigned char*)digest, &md5_ctx);
md5_str = Hex::hex(digest, 16);
delete digest;
}
return md5_str;
}
std::string Hash::sha1() {
if(!sha1_str.length()) {
finished = true;
char* digest = new char[20];
SHA1_Final((unsigned char*)digest, &sha1_ctx);
sha1_str = Hex::hex(digest, 20);
delete digest;
}
return sha1_str;
}
|