この記事では、Javaの16進数の文字列の取得・変換方法について紹介します。「そもそも16進数って何だっけ…?」という場合は、以下の記事で詳しく書いているので、参考にしてみてください。
【関連記事】
▶︎【JAVA】基本的な知識を身に着ける!16進数について分かりやすく解説。
Javaで文字列を16進数表記で取得
まずは、特定の文字列を16進数表記で取得してみます。記述例としては、次の通りです。
■記述例 import java.io.UnsupportedEncodingException; public class Main { public static void main(String args[]){ String str = "ポテパンスタイル"; for (char c : str.toCharArray()) { // 16進数表記で表示 System.out.println(Character.toString(c) + ":" + HexString(c)); } } // 16進数に変換する関数 private static String HexString(char c) { try { String s = Character.toString(c); byte[] buf = s.getBytes("Windows-31J"); String result = "0x"; for (byte b : buf) { result += String.format("%02x", b); } return result; } catch (UnsupportedEncodingException e) { return "Exception"; } } }
少し要素を分解して、全体像を見ていきましょう。
String str = "ポテパンスタイル"; for (char c : str.toCharArray()) { // 16進数表記で表示 System.out.println(Character.toString(c) + ":" + HexString(c)); }
今回の例では、string型の文字列 ”ポテパンスタイル” を16進数表記に変換しています。
toCharArrayメソッドは、文字の文字列配列を変換するメソッドです。この toCharArrayメソッド で、文字数分 for文を回しています。そして、Characterクラスの toStringメソッド で1文字ずつString型で文字を表示します。
「:」の後ろで使っている HexString関数 は、16進数表記に変換するための独自関数です。こちらについても、内容を確認していきましょう。
// 16進数に変換する関数 private static String HexString(char c) { try { String s = Character.toString(c); byte[] buf = s.getBytes("Windows-31J"); String result = "0x"; for (byte b : buf) { result += String.format("%02x", b); } return result; } catch (UnsupportedEncodingException e) { return "Exception"; } }
HexString関数は、1文字ずつ16進数表記に変換したい文字を引数に渡しています。
try-catch文 で例外発生を考慮したプログラムにしました。「try-catch文 の使い方ってよくわからないんだよなぁ…」という場合は、以下の記事が役立つと思うので、参考にしてみてください。
【関連記事】
▶︎【Java】try-catch文の基本を解説!例外・エラー処理をマスターしよう【サンプルあり】
実際に、16進数表記に変換しているのは try文 の中身なので、こちらを説明します。同じく、Characterクラスの toStringメソッド でString型に変換します。byte型配列の buf に、getBytesメソッドで文字列を “Windows-31J”にエンコードしました。
getBytesメソッドは、引数に指定した文字列をバイトシーケンスにエンコードし、Byte型配列として結果を取得するメソッドのことです。
そして最後に、formatメソッドで文字列を整形し、結果として return しています。formatメソッドについては、以下の記事を参照してみてください。
【関連記事】
▶︎Javaのformatメソッドの使い方を徹底的に解説!
上記の処理を実行すると、次のように結果を取得できます。
■実行結果 mbp:Desktop potepan$ java Main ポ:0x837c テ:0x8365 パ:0x8370 ン:0x8393 ス:0x8358 タ:0x835e イ:0x8343 ル:0x838b
それぞれの文字に対応した16進数表記を、結果として取得できました!
16進数表記の文字列をint型に変換
前章で、文字列を16進数表記で返す方法を見ていきました。ここでは、少し趣向を変えて、文字列をint型(10進数)に変換する方法を紹介します。記述例として、まずは全体のプログラムを確認しましょう。
■記述例 import java.util.LinkedList; public class Main { public static void main(String args[]){ // 「ポテパンスタイル」の文字列の16進数表記 String strHex = "837c8365837083938358835e8343838b"; LinkedList<String> list = new LinkedList<String>(); int i = 0; // 1文字分ごとにリストに格納 while (i < strHex.length()) { list.add( strHex.substring( i, Math.min( i + 4,strHex.length() ) ) ); i += 4; } // 出力時に16進数をint型に変換 while ((!list.isEmpty())){ System.out.println( (int)Long.parseLong(list.pop(), 16) ); } } }
ここでも、それぞれの内容を分解して説明します。
// 「ポテパンスタイル」の文字列の16進数表記 String strHex = "837c8365837083938358835e8343838b"; LinkedList<String> list = new LinkedList<String>(); int i = 0;
まずは、int型に変換したい16進数表記の文字を定義します。
ここでは、前章の結果で取得した ポテパンスタイル の16進数表記を使っています。LinkedListクラスで定義した list を使用します。LinkedListクラスは、ListクラスとDequeクラスのインターフェースを実装している、双方向結合リストのことです。
要素の追加・削除スピードが速いといった特徴があります。ここでは、結果を出力する際に文字順で取得したいことから、LinkedListクラスを使用しています。
// 1文字分ごとにリストに格納 while (i < strHex.length()) { list.add( strHex.substring( i, Math.min( i + 4,strHex.length() ) ) ); i += 4; }
上記部分のプログラムで、16進数表記の文字列を1文字ずつ分けています。
16進数表記は、前章の結果を見た通り4桁ずつの16進数で表現されていました。そのため、4桁ずつ値をリストに格納することで、1文字分のデータを取得できます。
while文で strHex の長さ分(文字数分)回し、substringメソッド で文字列として抜き出しました。while文については、こちらを参考にしてくださいね。
【関連記事】
▶︎whileでJavaの繰り返しの基本を学ぶ! forとの使い分けも解説
抜き出す文字数は、Mathクラスの minメソッド で4文字ずつで抜き出しています。
minメソッドは、2つの数を比較した上でどちらか小さい値を取得するメソッドです。ここでは、「4(i + 4)」と「strHex(837c8365837083938358835e8343838b)」を比較しています。明らかに 4 の方が小さいため、常に4で取得することになるということですね。
// 出力時に16進数をint型に変換 while ((!list.isEmpty())){ System.out.println( (int)Long.parseLong(list.pop(), 16) ); }
最後に、上記の処理でint型の値を出力しています。
「!list.isEmpty()」で、リストが空になるまでwhile文を回しています。list.pop() で、リストの中身をポップしているのがわかりますね。Longクラスの parseLongメソッド で、文字列の引数を符号付き 10 進数の long 型としています。
第二引数に 16 を指定することで、16進数が基数になっています。以上の処理を実行すると、次のようにint型で16進数表記の文字列を取得できます。
■実行結果 mbp:Desktop potepan$ java Main 33660 33637 33648 33683 33624 33630 33603 33675
進数変換ツールなどを使えばわかりますが、ちゃんと16進数が10進数に変換されているのが確認できます。
まとめ
今回は、16進数の文字列を変換する方法について解説しました。処理は少し複雑になりますが、しっかり内容を追うことで実装可能です。ぜひ参考に、変換を行ってみてください!
バイトシーケンスは、8桁の2進数のまとまりを意味します!