| 278 | */ |
| 279 | |
| 280 | inline std::string SHA1::final() |
| 281 | { |
| 282 | /* Total number of hashed bits */ |
| 283 | uint64_t total_bits = (transforms*BLOCK_BYTES + buffer.size()) * 8; |
| 284 | |
| 285 | /* Padding */ |
| 286 | buffer += (char)0x80; |
| 287 | size_t orig_size = buffer.size(); |
| 288 | while (buffer.size() < BLOCK_BYTES) |
| 289 | { |
| 290 | buffer += (char)0x00; |
| 291 | } |
| 292 | |
| 293 | uint32_t block[BLOCK_INTS]; |
| 294 | buffer_to_block(buffer, block); |
| 295 | |
| 296 | if (orig_size > BLOCK_BYTES - 8) |
| 297 | { |
| 298 | transform(digest, block, transforms); |
| 299 | for (size_t i = 0; i < BLOCK_INTS - 2; i++) |
| 300 | { |
| 301 | block[i] = 0; |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | /* Append total_bits, split this uint64_t into two uint32_t */ |
| 306 | block[BLOCK_INTS - 1] = (uint32_t)total_bits; |
| 307 | block[BLOCK_INTS - 2] = (uint32_t)(total_bits >> 32); |
| 308 | transform(digest, block, transforms); |
| 309 | |
| 310 | /* Hex std::string */ |
| 311 | std::ostringstream result; |
| 312 | for (size_t i = 0; i < sizeof(digest) / sizeof(digest[0]); i++) |
| 313 | { |
| 314 | result << std::hex << std::setfill('0') << std::setw(8); |
| 315 | result << digest[i]; |
| 316 | } |
| 317 | |
| 318 | /* Reset for next run */ |
| 319 | reset(digest, buffer, transforms); |
| 320 | |
| 321 | return result.str(); |
| 322 | } |
| 323 | |
| 324 | |
| 325 | inline std::string SHA1::from_file(const std::string &filename) |
no test coverage detected