Created
October 10, 2017 20:23
-
-
Save arrieta/7d2e196c40514d8b5e9031f2535064fc to your computer and use it in GitHub Desktop.
Calculate and display the SHA-256 hash of a list of files using OpenSSL from C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -*- coding:utf-8; mode:c++; mode:auto-fill; fill-column:80; -*- | |
/// @file sha256.cpp | |
/// @brief Calculate and display the SHA-256 hash of a list of files. | |
/// @author J. Arrieta <[email protected]> | |
/// @date October 10, 2017 | |
/// @copyright (c) 2017 Nabla Zero Labs | |
/// @license MIT License | |
/// | |
/// Compiled in macOS High Sierra 10.13 (previous installation of OpenSSL 1.1.0). | |
/// | |
/// $ clang++ sha256.cpp -osha256 -std=c++1z -Wall -Wextra -march=native \ | |
/// -Ofast -lssl -lcrypto | |
/// $ ./sha256 | |
/// usage: ./sha256 FILE_1 [FILE_2 [... [FILE_N]]] | |
/// $ ./sha256 sha256 | |
/// f4774d172b9177109045759ada55f55a47a602c0b0392330d5c4b79e9d474fb0 sha256 | |
/// | |
// C++ Standard Library | |
#include <cstdlib> | |
#include <cerrno> | |
#include <cstring> | |
#include <fstream> | |
#include <iostream> | |
#include <iomanip> | |
#include <sstream> | |
#include <string> | |
#include <stdexcept> | |
// OpenSSL Library | |
#include <openssl/sha.h> | |
inline std::string | |
SHA256(const char* const path) | |
{ | |
std::ifstream fp(path, std::ios::in | std::ios::binary); | |
if (not fp.good()) { | |
std::ostringstream os; | |
os << "Cannot open \"" << path << "\": " << std::strerror(errno) << "."; | |
throw std::runtime_error(os.str()); | |
} | |
constexpr const std::size_t buffer_size { 1 << 12 }; | |
char buffer[buffer_size]; | |
unsigned char hash[SHA256_DIGEST_LENGTH] = { 0 }; | |
SHA256_CTX ctx; | |
SHA256_Init(&ctx); | |
while (fp.good()) { | |
fp.read(buffer, buffer_size); | |
SHA256_Update(&ctx, buffer, fp.gcount()); | |
} | |
SHA256_Final(hash, &ctx); | |
fp.close(); | |
std::ostringstream os; | |
os << std::hex << std::setfill('0'); | |
for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) { | |
os << std::setw(2) << static_cast<unsigned int>(hash[i]); | |
} | |
return os.str(); | |
} | |
int | |
main(int argc, char* argv[]) | |
{ | |
if (argc < 2) { | |
std::cerr << "usage: " << argv[0] << " FILE_1 [FILE_2 [... [FILE_N]]]" << std::endl; | |
return EXIT_FAILURE; | |
} | |
for (int arg = 1; arg < argc; ++arg) { | |
try { | |
std::cout << SHA256(argv[arg]) << " " << argv[arg] << std::endl; | |
} catch(const std::exception& e) { | |
std::cerr << "[fatal] " << e.what() << std::endl; | |
} | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment