読者です 読者をやめる 読者になる 読者になる

「Java」文字列をそのままの形でバイト列にする

Java

わかりにくいタイトルですが、例えば、"ABCDEF" という文字列があった場合、String#getBytes でバイト列を得ると "{41,42,43,44,45,46}" となりますが、そうではなくてそのまま形 "{AB,CD,EF}" というバイト列を得るというサンプルコードを書いてみました。

■ HexStringTest.java

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class HexStringTest {
  public static void main(String[] args) {
    
    String s = "ABCDEF"; // ( *0 )
    byte[] b = new byte[s.length() / 2]; // ( *1 )
    
    for (int i = 0; i < s.length(); i += 2) { // ( *2 )
      String ss = s.substring(i, i + 2);
      b[i / 2] = (byte) Integer.parseInt(ss, 16); // ( *3 )
    }

    try (FileOutputStream fos = new FileOutputStream("output.txt");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();) {
      for (byte bb : b) {
        baos.write(bb);
      }
      baos.writeTo(fos);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}


( *0 ) 16 進数で表されたバイナリが前提なので、文字列長は偶数、文字の範囲は 0 ~ F になります。

( *1 ) 文字列長の半分の長さのバイト配列を宣言する。16 進数は "AB" なりで 1 バイトになるので、文字列長を 2 で割った数がバイト列の長さになるはず。

( *2 ) String#substring で 2 文字ずつ ( 1 バイト相当 ) を得たいので for の増分は 2 とする。

( *3 ) Integer#parseInt で *2 で得た文字列を 16 進数の数字に変換し、*1 で宣言したバイト配列に格納する。バイト配列の添字は 1 ずつ増やしたいので i を 2 で割る。

なんとなく確認しやすいようにファイルに出力してます。output.txt をバイナリエディタなりで確認すると AB CD EF というバイナリが書き込まれているはずです。


もっといい方法がありそうな気もしますが、そんなに使う場面もなさそうですし、このあたりとしておきます。

以上です。