Skip to content

Commit 779747f

Browse files
committed
Add the SHA1 Utility (Not sure we'll use this yet)
1 parent 3385166 commit 779747f

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

Source/Utility/SHA1.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#include <iostream>
2+
#include <fstream>
3+
#include <iomanip>
4+
#include <sstream>
5+
#include <vector>
6+
#include <cstdint>
7+
#include <cstring>
8+
#include <filesystem>
9+
10+
#include "Utility/SHA1.h"
11+
12+
class SHA1 {
13+
public:
14+
SHA1() { reset(); }
15+
16+
void update(const uint8_t* data, size_t len) {
17+
for (size_t i = 0; i < len; ++i) {
18+
block[blockByteIndex++] = data[i];
19+
byteCount++;
20+
if (blockByteIndex == 64) {
21+
processBlock();
22+
blockByteIndex = 0;
23+
}
24+
}
25+
}
26+
27+
void finalize() {
28+
block[blockByteIndex++] = 0x80;
29+
if (blockByteIndex > 56) {
30+
while (blockByteIndex < 64)
31+
block[blockByteIndex++] = 0;
32+
processBlock();
33+
blockByteIndex = 0;
34+
}
35+
36+
while (blockByteIndex < 56)
37+
block[blockByteIndex++] = 0;
38+
39+
uint64_t bitCount = byteCount * 8;
40+
for (int i = 7; i >= 0; --i)
41+
block[blockByteIndex++] = static_cast<uint8_t>((bitCount >> (i * 8)) & 0xFF);
42+
43+
processBlock();
44+
}
45+
46+
std::string hexDigest() const {
47+
std::ostringstream result;
48+
for (int i = 0; i < 5; ++i)
49+
result << std::hex << std::setw(8) << std::setfill('0') << hash[i];
50+
return result.str();
51+
}
52+
53+
private:
54+
uint32_t hash[5];
55+
uint8_t block[64];
56+
size_t blockByteIndex = 0;
57+
uint64_t byteCount = 0;
58+
59+
static uint32_t rotateLeft(uint32_t value, uint32_t bits) {
60+
return (value << bits) | (value >> (32 - bits));
61+
}
62+
63+
void reset() {
64+
hash[0] = 0x67452301;
65+
hash[1] = 0xEFCDAB89;
66+
hash[2] = 0x98BADCFE;
67+
hash[3] = 0x10325476;
68+
hash[4] = 0xC3D2E1F0;
69+
blockByteIndex = 0;
70+
byteCount = 0;
71+
}
72+
73+
void processBlock() {
74+
uint32_t w[80];
75+
for (int i = 0; i < 16; ++i) {
76+
w[i] = (static_cast<uint32_t>(block[i * 4]) << 24) |
77+
(static_cast<uint32_t>(block[i * 4 + 1]) << 16) |
78+
(static_cast<uint32_t>(block[i * 4 + 2]) << 8) |
79+
(static_cast<uint32_t>(block[i * 4 + 3]));
80+
}
81+
82+
for (int i = 16; i < 80; ++i)
83+
w[i] = rotateLeft(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
84+
85+
uint32_t a = hash[0];
86+
uint32_t b = hash[1];
87+
uint32_t c = hash[2];
88+
uint32_t d = hash[3];
89+
uint32_t e = hash[4];
90+
91+
for (int i = 0; i < 80; ++i) {
92+
uint32_t f, k;
93+
if (i < 20) {
94+
f = (b & c) | (~b & d);
95+
k = 0x5A827999;
96+
} else if (i < 40) {
97+
f = b ^ c ^ d;
98+
k = 0x6ED9EBA1;
99+
} else if (i < 60) {
100+
f = (b & c) | (b & d) | (c & d);
101+
k = 0x8F1BBCDC;
102+
} else {
103+
f = b ^ c ^ d;
104+
k = 0xCA62C1D6;
105+
}
106+
uint32_t temp = rotateLeft(a, 5) + f + e + k + w[i];
107+
e = d;
108+
d = c;
109+
c = rotateLeft(b, 30);
110+
b = a;
111+
a = temp;
112+
}
113+
114+
hash[0] += a;
115+
hash[1] += b;
116+
hash[2] += c;
117+
hash[3] += d;
118+
hash[4] += e;
119+
}
120+
};
121+
122+
std::string sha1_from_file(const std::filesystem::path& filename) {
123+
SHA1 sha1;
124+
std::ifstream file(filename, std::ios::binary);
125+
std::vector<uint8_t> buffer(65536);
126+
127+
while (file) {
128+
file.read(reinterpret_cast<char*>(buffer.data()), buffer.size());
129+
sha1.update(buffer.data(), file.gcount());
130+
}
131+
132+
sha1.finalize();
133+
return sha1.hexDigest();
134+
}

Source/Utility/SHA1.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <filesystem>
5+
6+
7+
std::string sha1_from_file(const std::filesystem::path& filename);

0 commit comments

Comments
 (0)