C++ で簡単にメッセージダイジェスト(MD5, SHA1, SHA224, SHA256, SHA384, SHA512)を求めたい。
C++xx でも流石に本体には入って来そうにないよねと。
とりあえず Boost くらいで出来ると助かるなぁと、「boost sha」でググってみたら
SHA1 は boost/uuid/sha1.hpp で計算できることが分かったのだが、これは UUID 求めるために SHA1 が必要なので、
それを流用できるという事のようで、メッセージダイジェスト用に用意されたものではないっぽい。
前に Crypto++ ってのを見かけたなぁ、と思って探してみたのだが、どうも Cygwin の標準パッケージには入ってなさそうなので面倒くさい。
という事で、ちょっと大仰だけど、定番は OpenSSL かな?という事で、
「openssl c++ gcc md5 sha1 sha256 sha512」でググって以下のページを見つけてきた。
C++xx でも流石に本体には入って来そうにないよねと。
とりあえず Boost くらいで出来ると助かるなぁと、「boost sha」でググってみたら
SHA1 は boost/uuid/sha1.hpp で計算できることが分かったのだが、これは UUID 求めるために SHA1 が必要なので、
それを流用できるという事のようで、メッセージダイジェスト用に用意されたものではないっぽい。
前に Crypto++ ってのを見かけたなぁ、と思って探してみたのだが、どうも Cygwin の標準パッケージには入ってなさそうなので面倒くさい。
という事で、ちょっと大仰だけど、定番は OpenSSL かな?という事で、
「openssl c++ gcc md5 sha1 sha256 sha512」でググって以下のページを見つけてきた。
- HHeLiBeXの日記 正道編 / 2017-11-25: 各言語でメッセージダイジェスト
- blog@kenzauros.com / 2015-06-15: C言語OpenSSLでSHA256ハッシュ計算
こんな感じだろうか?
必要なヘッダ
16進文字列化
各ダイジェスト
なんか、ハッシュ毎に関数や構造体の名前が微妙に統一されてないのが何とも。
あと、コンパイルの際には -lcrypto が必要となる。
必要なヘッダ
#include <iomanip> #include <sstream> #include <openssl/md5.h> #include <openssl/sha.h>
16進文字列化
std::string hash2str(unsigned char *hash, const size_t &len) { std::stringstream ss; ss << std::setfill('0') << std::hex; for(int i = 0; i < len; i++) { ss << std::setw(2) << static_cast<int>(hash[i]); } return ss.str(); }
各ダイジェスト
template<class T> std::string md5(const T *data, const size_t &n) { unsigned char hash[MD5_DIGEST_LENGTH]; MD5_CTX c; MD5_Init(&c); MD5_Update(&c, static_cast<const void *>(data), n * sizeof(*data)); MD5_Final(hash, &c); return hash2str(hash, sizeof(hash)); }
template<class T> std::string sha1(const T *data, const size_t &n) { unsigned char hash[SHA_DIGEST_LENGTH]; SHA_CTX c; SHA1_Init(&c); SHA1_Update(&c, static_cast<const void *>(data), n * sizeof(*data)); SHA1_Final(hash, &c); return hash2str(hash, sizeof(hash)); }
template<class T> std::string sha224(const T *data, const size_t &n) { unsigned char hash[SHA224_DIGEST_LENGTH]; SHA256_CTX c; SHA224_Init(&c); SHA224_Update(&c, static_cast<const void *>(data), n * sizeof(*data)); SHA224_Final(hash, &c); return hash2str(hash, sizeof(hash)); }
template<class T> std::string sha256(const T *data, const size_t &n) { unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX c; SHA256_Init(&c); SHA256_Update(&c, static_cast<const void *>(data), n * sizeof(*data)); SHA256_Final(hash, &c); return hash2str(hash, sizeof(hash)); }
template<class T> std::string sha384(const T *data, const size_t &n) { unsigned char hash[SHA384_DIGEST_LENGTH]; SHA512_CTX c; SHA384_Init(&c); SHA384_Update(&c, static_cast<const void *>(data), n * sizeof(*data)); SHA384_Final(hash, &c); return hash2str(hash, sizeof(hash)); }
template<class T> std::string sha512(const T *data, const size_t &n) { unsigned char hash[SHA512_DIGEST_LENGTH]; SHA512_CTX c; SHA512_Init(&c); SHA512_Update(&c, static_cast<const void *>(data), n * sizeof(*data)); SHA512_Final(hash, &c); return hash2str(hash, sizeof(hash)); }
なんか、ハッシュ毎に関数や構造体の名前が微妙に統一されてないのが何とも。
あと、コンパイルの際には -lcrypto が必要となる。
タグ
コメントをかく