18
18
#include < iomanip> // / For std::setfill and std::setw
19
19
#include < iostream> // / For IO operations
20
20
#include < sstream> // / For std::stringstream
21
+ #include < vector> // / For std::vector
21
22
22
23
/* *
23
24
* @namespace hashing
@@ -35,7 +36,7 @@ namespace sha256 {
35
36
* @param input Input string
36
37
* @return std::string The padded input string
37
38
*/
38
- std::string prepare_input (const std::string& input) {
39
+ std::string prepare_input (const std::string & input) {
39
40
// Pre-processing
40
41
std::string padded_input = input;
41
42
uint64_t input_size = input.length () * 8 ; // Message length in bits
@@ -65,11 +66,11 @@ uint32_t right_rotate(uint32_t n, size_t rotate) {
65
66
}
66
67
67
68
/* *
68
- * @brief The SHA-256 algorithm
69
- * @param input The input string to hash
70
- * @return std::string The final hash value
69
+ * @brief Computes the final hash array
70
+ * @param padded_input Padded input string
71
+ * @return std::array<uint32_t, 8> The final hash array
71
72
*/
72
- std::string sha256 (const std::string& input ) {
73
+ std::array< uint32_t , 8 > compute_hash (const std::string &padded_input ) {
73
74
// Initialize array of hash values with first 32 bits of the fractional
74
75
// parts of the square roots of the first 8 primes 2..19
75
76
std::array<uint32_t , 8 > hash = {0x6A09E667 , 0xBB67AE85 , 0x3C6EF372 ,
@@ -91,8 +92,6 @@ std::string sha256(const std::string& input) {
91
92
0x5B9CCA4F , 0x682E6FF3 , 0x748F82EE , 0x78A5636F , 0x84C87814 , 0x8CC70208 ,
92
93
0x90BEFFFA , 0xA4506CEB , 0xBEF9A3F7 , 0xC67178F2 };
93
94
94
- const std::string padded_input = prepare_input (input);
95
-
96
95
// Process message in successive 512-bit (64-byte) chunks
97
96
for (size_t i = 0 ; i < padded_input.length (); i += 64 ) {
98
97
std::array<uint32_t , 64 > blocks{};
@@ -158,7 +157,15 @@ std::string sha256(const std::string& input) {
158
157
hash[7 ] += h;
159
158
}
160
159
161
- // Convert the hash to a hexadecimal string
160
+ return hash;
161
+ }
162
+
163
+ /* *
164
+ * @brief Convert the hash to a hexadecimal string
165
+ * @param hash Hash array
166
+ * @return std::string Final hash value
167
+ */
168
+ std::string hash_to_string (const std::array<uint32_t , 8 > &hash) {
162
169
std::string result;
163
170
for (size_t i = 0 ; i < 8 ; ++i) {
164
171
for (size_t j = 0 ; j < 4 ; ++j) {
@@ -171,6 +178,21 @@ std::string sha256(const std::string& input) {
171
178
172
179
return result;
173
180
}
181
+
182
+ /* *
183
+ * @brief The SHA-256 algorithm
184
+ * @param input The input string to hash
185
+ * @return std::string The final hash value
186
+ */
187
+ std::string sha256 (const std::string &input) {
188
+ const std::string padded_input = prepare_input (input);
189
+
190
+ std::array<uint32_t , 8 > hash = compute_hash (padded_input);
191
+
192
+ std::string result = hash_to_string (hash);
193
+
194
+ return result;
195
+ }
174
196
} // namespace sha256
175
197
} // namespace hashing
176
198
@@ -179,49 +201,29 @@ std::string sha256(const std::string& input) {
179
201
* @returns void
180
202
*/
181
203
static void test () {
182
- // 1st Test
183
- std::string input = " " ;
184
- std::string expected =
185
- " e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ;
186
- std::string output = hashing::sha256::sha256 (input);
187
- std::cout << " Input: " << input << std::endl;
188
- std::cout << " Expected: " << expected << std::endl;
189
- std::cout << " Output: " << output << std::endl;
190
- assert (output == expected);
191
- std::cout << " 1st TEST PASSED\n\n " ;
192
-
193
- // 2nd Test
194
- input = " test" ;
195
- expected =
196
- " 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" ;
197
- output = hashing::sha256::sha256 (input);
198
- std::cout << " Input: " << input << std::endl;
199
- std::cout << " Expected: " << expected << std::endl;
200
- std::cout << " Output: " << output << std::endl;
201
- assert (output == expected);
202
- std::cout << " 2nd TEST PASSED\n\n " ;
203
-
204
- // 3rd Test
205
- input = " Hello World" ;
206
- expected =
207
- " a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e" ;
208
- output = hashing::sha256::sha256 (input);
209
- std::cout << " Input: " << input << std::endl;
210
- std::cout << " Expected: " << expected << std::endl;
211
- std::cout << " Output: " << output << std::endl;
212
- assert (output == expected);
213
- std::cout << " 3rd TEST PASSED\n\n " ;
214
-
215
- // 4th Test
216
- input = " Hello World!" ;
217
- expected =
218
- " 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069" ;
219
- output = hashing::sha256::sha256 (input);
220
- std::cout << " Input: " << input << std::endl;
221
- std::cout << " Expected: " << expected << std::endl;
222
- std::cout << " Output: " << output << std::endl;
223
- assert (output == expected);
224
- std::cout << " 4th TEST PASSED\n\n " ;
204
+ struct TestCase {
205
+ const std::string input;
206
+ const std::string expected_hash;
207
+ TestCase (std::string input, std::string expected_hash)
208
+ : input(std::move(input)),
209
+ expected_hash (std::move(expected_hash)) {}
210
+ };
211
+ const std::vector<TestCase> test_cases{
212
+ TestCase (
213
+ " " ,
214
+ " e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ),
215
+ TestCase (
216
+ " test" ,
217
+ " 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" ),
218
+ TestCase (
219
+ " Hello World" ,
220
+ " a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e" ),
221
+ TestCase (" Hello World!" ,
222
+ " 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9"
223
+ " 069" )};
224
+ for (const auto &tc : test_cases) {
225
+ assert (hashing::sha256::sha256 (tc.input ) == tc.expected_hash );
226
+ }
225
227
}
226
228
227
229
/* *
0 commit comments