- PR -

16進文字列をバイナリに変換したい

1
投稿者投稿内容
WISSEN
会議室デビュー日: 2004/03/17
投稿数: 3
投稿日時: 2004-12-04 21:02
基本的な質問ですが、教えてください。

16進文字列でもらったデータを、バイナリに戻す処理を書いています。
ByteクラスのparseByteを使用していますが、0x80を超える数で
NumberFormatException になってしまいます。

"15a1145e81" のような String を byte[]に変換したいのですが、
どのような方法を使えば良いのでしょうか。
どなたか、ご教授いただけませんでしょうか。よろしくお願い致します。
ぼんじぃ
ベテラン
会議室デビュー日: 2004/05/21
投稿数: 70
投稿日時: 2004-12-04 21:43
とりあえずどのようなソースコードを使用して、何を変換して、どこで例外が発生したのか示していただけないと何とも言えない感じがします。



[ メッセージ編集済み 編集者: ぼんじぃ 編集日時 2004-12-04 21:44 ]
WISSEN
会議室デビュー日: 2004/03/17
投稿数: 3
投稿日時: 2004-12-04 22:01
失礼致しました。
ソースは以下の通りです。

String str = "15a1145e8128d9c389e0aa87dfa2da4d7b0ed990" ;
byte[] b_pwd = new byte[20];
for (int i=0;i<20;i++){
String sub_str = str.substring(i*2,(i+1)*2);
System.out.println(sub_str);
b_pwd[i]=Byte.parseByte(sub_str,16);
}

出力は以下の通りです。
15
a1
java.lang.NumberFormatException
at java.lang.Byte.parseByte(Byte.java:88)
at test.DocTest.main(DocTest.java:23)
Exception in thread "main"

"0x15"は処理できているのに、
"0xa1"の処理では失敗してしまいます。

申し訳ございませんが、お知恵を拝借できませんでしょうか。
Odakaz
ベテラン
会議室デビュー日: 2004/05/24
投稿数: 70
投稿日時: 2004-12-05 00:00
引用:

WISSENさんの書き込み (2004-12-04 22:01) より:
出力は以下の通りです。
15
a1
java.lang.NumberFormatException
at java.lang.Byte.parseByte(Byte.java:88)
at test.DocTest.main(DocTest.java:23)
Exception in thread "main"

"0x15"は処理できているのに、
"0xa1"の処理では失敗してしまいます。


0xa1を単純に10進数にすると161となるので、これがbyteの範囲(-128〜127)を
はみ出てしまっているんじゃないでしょうか?
対策としては、いったんIntegerにしてそこからbyteValue()するとかどうでしょう

[ メッセージ編集済み 編集者: Odakaz 編集日時 2004-12-05 00:03 ]
ぼんじぃ
ベテラン
会議室デビュー日: 2004/05/21
投稿数: 70
投稿日時: 2004-12-05 21:30
そうですねByte#parseByteを使うと仕様なのか例外が出ますね。

Odakaz様の言うとおり、一度intに直してやった方がいいですね。
一応サンプルです。
コード:
	String source = "15a1145e8128d9c389e0aa87dfa2da4d7b0ed990";
	byte[] result = null;
	int high, low;
	byte b;
	
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	for(int i = 0; i < source.length(); i+=2){
		high = Integer.parseInt(source.substring(i, i + 1), 16);
		low = Integer.parseInt(source.substring(i + 1, i + 2), 16);
		b = (byte)(high * 16 + low);
		baos.write(b);
	}
		
	result = baos.toByteArray();

kito
ベテラン
会議室デビュー日: 2003/03/24
投稿数: 59
お住まい・勤務地: Osaka
投稿日時: 2004-12-06 00:43
引用:

ぼんじぃさんの書き込み (2004-12-05 21:30) より:

Odakaz様の言うとおり、一度intに直してやった方がいいですね。
一応サンプルです。


highとかlowとかは普通必要ないのでは?
コード:
String source = "15a1145e8128d9c389e0aa87dfa2da4d7b0ed990";

ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(int i = 0; i < source.length(); i += 2){
	int b = Integer.parseInt(source.substring(i, i + 2), 16);
	baos.write(b);
}
byte[] result = baos.toByteArray();


WISSEN
会議室デビュー日: 2004/03/17
投稿数: 3
投稿日時: 2004-12-06 10:08
ぼんじぃ 様、kito 様、Odakaz 様
ご回答戴き、有難うございました!
なるほど、一旦int型に変換すれば、byteの範囲内に収めることができるのですね。

おかげさまで、思ったとおりの動きができるようになりました。
大変助かりました。本当に有難うございました。
1

スキルアップ/キャリアアップ(JOB@IT)