C++ で OpenSSL をライブラリとして用いて
MD5, SHA1, SHA256, SHA512 等のメッセージダイジェストを求めた後、16進表示したかった。
そこで、「std::string hex」でググって出てきた
「stringstream hex padding」でググって出てきた
以下のようなコードを書いたのだが
結果が
MD5, SHA1, SHA256, SHA512 等のメッセージダイジェストを求めた後、16進表示したかった。
そこで、「std::string hex」でググって出てきた
- MaryCore / 2018-10-11: C++ 数値を 2進数 8進数 10進数 16進数 文字列に変換する方法
- stackoverflow / 2009-08-10: How can I append data to a std::string in hex format?
「stringstream hex padding」でググって出てきた
- stackoverflow / 2010-03-02: How do I use a manipulator to format my hex output with padded left zeros
以下のようなコードを書いたのだが
#include <iostream> #include <sstream> #include <iomanip> int main(int argc, char * argv[]) { unsigned char x[] = {0x01, 0x23, 0x45, 0x67}; std::stringstream ss; ss << std::setfill('0') << std::hex; for (int i = 0; i < sizeof(x); i++) { ss << std::setw(2); ss << x[i]; } std::cout << ss.str() << std::endl; return 0; }
$ g++ sstest.cpp && ./a 0#Egみたいになった。
どうも、char や unsigned char を食わせるのが良くないらしい。
数値ではなく文字扱いされているという事のようだ。
static_cast で short や int に直してやると大丈夫だった。
結果
差分
static_cast を使うとどうも野暮ったいので暗黙の型変換を使ったほうがコンパクトで読み易いだろうか?
あと、
std::setfill() と std::hex はあらかじめ設定しておけば、以降の入力に対して有効なようだが、
std::setw() は各入力毎に必要な模様。
数値ではなく文字扱いされているという事のようだ。
static_cast で short や int に直してやると大丈夫だった。
#include <iostream> #include <sstream> #include <iomanip> int main(int argc, char * argv[]) { unsigned char x[] = {0x01, 0x23, 0x45, 0x67}; std::stringstream ss; ss << std::setfill('0') << std::hex; for (int i = 0; i < sizeof(x); i++) { ss << std::setw(2); ss << static_cast<int>(x[i]); } std::cout << ss.str() << std::endl; return 0; }
$ g++ sstest2.cpp && ./a 01234567
差分
$ diff sstest{,2}.cpp 12c12 < ss << x[i]; --- > ss << static_cast<int>(x[i]);
static_cast を使うとどうも野暮ったいので暗黙の型変換を使ったほうがコンパクトで読み易いだろうか?
$ diff sstest{,3}.cpp 12c12 < ss << x[i]; --- > ss << 0 + x[i];
$ diff sstest{2,3}.cpp 12c12 < ss << static_cast<int>(x[i]); --- > ss << 0 + x[i];
あと、
std::setfill() と std::hex はあらかじめ設定しておけば、以降の入力に対して有効なようだが、
std::setw() は各入力毎に必要な模様。
タグ
コメントをかく