1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iconvで文字コード変換と、16進数文字列変換

Posted at
a.cpp


# include <stdio.h>
# include <stdlib.h>
# include <iconv.h>
# include <errno.h>
# include <string.h>
# include <sys/types.h>

# include <string>

std::string encode( const u_char *input_string, size_t input_length, std::string input_code, std::string output_code ) {
	
	if( input_string == NULL ) {
		
		fprintf( stderr, "input string is empty.\n" );
		return( "" );
		
	}
	
	if( input_length == 0 ) {
		
		fprintf( stderr, "input length is zero.\n" );
		return( "" );
		
	}
	
	if( input_code.empty() ) {
		
		// iconvに文字列判定機能は無い。
		// 入力した文字列の文字コードを与える必要がある。
		fprintf( stderr, "input code is empty.\n" );
		return( "" );
		
	}
	
	if( output_code.empty() ) {
		
		// 変換したい文字コードが無い場合は、
		// ひとまず、自分の環境の文字コードに変換されるようにしておく。
		output_code = "UTF-8";
		
	}
	
	iconv_t ic;
	
	size_t str_in_length = input_length;
	size_t str_out_length = input_length * 3; // 変換後のバイト数がどうなるか分からない。1バイトが3バイトになることを考慮しておく。
	
	char str_in[str_in_length+1];
	char str_out[str_out_length+1];
	
	memset( str_in, 0, sizeof( str_in ) );
	memset( str_out, 0, sizeof( str_out ) );
	
	// const u_char -> char
	for( size_t i = 0; i < input_length; ++i ) {
		
		str_in[i] = (char)input_string[i];
		
	}
	
	// iconvに渡すのは、charの配列の先頭を指すポインタ、のポインタ。
	char *ptr_in  = str_in;
	char *ptr_out = str_out;
	
	errno = 0;
	
	ic = iconv_open( output_code.c_str(), input_code.c_str() );
	
	if( errno ) {
		
		fprintf( stderr, "iconv_open failed. %s\n", strerror( errno ) );
		return( "" );
		
	}
	
	// それぞれポインタを渡す。
	iconv( ic, &ptr_in, &str_in_length, &ptr_out, &str_out_length );
	
	if( errno ) {
		
		fprintf( stderr, "iconv failed. %s\n", strerror( errno ) );
		
		iconv_close( ic );
		return( "" );
		
	} else {
		
		iconv_close( ic );
		return( str_out );
		
	}
	
}
	
int main( int argc, char **argv ) {
	
	// input_stringで期待する文字列は、16進数文字列。大文字でも小文字でもかまわない。
	if( argc != 4 ) {
		
		printf( "./a.out input_code output_code input_string\n\n" );
		printf( "example:\n" );
		printf( "\t./a.out SHIFT-JIS UTF-8 4e69636520626f61742e\n\n" );
		return( 1 );
		
	}
	
	// 16進文字列を、数値に戻し、charの配列にする。
	size_t input_length = strlen( argv[3] );
	size_t input_length_half = input_length / 2;
	
	if( input_length_half == 0 ) {
		
		// 1文字も無い?
		fprintf( stderr, "input_string empty.\n" );
		return( 1 );
		
	}
	
	u_char input_string[input_length_half];
	u_char *input_string_p = input_string;
	
	for( size_t i = 0, ii = 0; i < input_length_half; ++i, ii += 2 ) {
		
		char tmp[2];
		strncpy( tmp, argv[3] + ii, 2 );
		tmp[2] = '\0';
		
		long num = strtol( tmp, NULL, 16 );
		*input_string_p++ = (u_char)num;
		
	}
	
	std::string ret = encode( input_string, input_length_half, argv[1], argv[2] );
	
	printf( "%s\n", ret.c_str() );
	
	return( 0 );
	
}


ノリで書いてみました。

細かいエラーチェックはしてないです。

実行すると以下のような感じに。


[todanano@localhost samba]$ g++ ./a.cpp
[todanano@localhost samba]$
[todanano@localhost samba]$
[todanano@localhost samba]$ ./a.out SHIFT-JIS UTF-8 82a0829f5e8160905382aa82d282e582f182d282e582f182b782e982f182b682e1829f5e8160
あぁ^~心がぴょんぴょんするんじゃぁ^~
[todanano@localhost samba]$
[todanano@localhost samba]$
[todanano@localhost samba]$ ./a.out UTF-8 UTF-8 e38182e381815eefbd9ee5bf83e3818ce381b4e38287e38293e381b4e38287e38293e38199e3828be38293e38198e38283e381815eefbd9e
あぁ^~心がぴょんぴょんするんじゃぁ^~
[todanano@localhost samba]$
[todanano@localhost samba]$
[todanano@localhost samba]$ ./a.out EUC-JP UTF-8 a4a2a4a15ea1c1bfb4a4aca4d4a4e7a4f3a4d4a4e7a4f3a4b9a4eba4f3a4b8a4e3a4a15ea1c1
あぁ^~心がぴょんぴょんするんじゃぁ^~
[todanano@localhost samba]$

文字列を16進数文字列にするには、以下のサイト様とかで。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?