hack のためのネタ帳, etc,,,

状況

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」でググって以下のページを見つけてきた。

実装

こんな感じだろうか?

必要なヘッダ
#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 が必要となる。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

フリーエリア

管理人/副管理人のみ編集できます