ちょくちょくデータを暗号化して16進数表記文字列に変換して保存し、保存された16進表記文字列をデータに復元する事をやるので、忘備録として記録する事に。こういう、ちょっとしたものでも、書こうと思ったら時間を取られる。
#include <string>
#include <iostream>
static int atob( int c ) {
static const unsigned char btbl[] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3
0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 4
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 5
0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 6
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 7
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 9
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // A
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // C
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // D
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // E
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // F
};
return btbl[ c ];
}
//! 16進文字列から unsigned char 配列への変換
/*
@note 16進文字列は、0-9, A-F のみを利用した表記で
1バイトを2文字で表記しているものとする。16進を示す 0x 等の
接頭辞は含まれていない。
*/
void hexstr2str(
const std::string& src,
std::string& dst
) {
dst.resize( (src.size() + 1) / 2 );
for(size_t i = 0; i < src.size(); i++) {
if( (i & 1) != 0 ) {
dst[ i / 2 ] |= atob( src[i] );
} else {
dst[ i / 2 ] = atob( src[i] ) << 4;
}
}
}
//! unsigned char 配列から 16進文字列への変換
/*!
@note 16進文字列は、0-9, A-F のみを利用した表記で
1バイトを2文字で表記したものに変換される。16進を示す 0x 等の
接頭辞は含まない。
*/
void str2hexstr(
const std::string& src,
std::string& dst
) {
static const char atbl[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
};
dst.resize( src.size() * 2 );
for( size_t i = 0; i < src.size(); i++ ) {
dst[i*2 ] = atbl[ ((src[i] >> 4) & 0x0F) ]; // & 0x0F しないと算術シフトでアウトでした
dst[i*2+1] = atbl[ (src[i] & 0x0F) ];
}
}
int main() {
std::string src = "Hello world!";
std::string hex, dst;
std::cout << src << std::endl;
str2hexstr( src, hex );
std::cout << hex << std::endl;
hexstr2str( hex, dst );
std::cout << dst << std::endl;
return 0;
}
結果
Hello world!
48656C6C6F20776F726C6421
Hello world!
2022/01/14 追記: str2hexstr のコメントに書いたバグ修正をしました