Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@niwasawa

Java のバイト配列を16進数表記の文字列に変換する

More than 1 year has passed since last update.

方法

JAXB の javax.xml.bind.DatatypeConverter クラスを利用する。

DatatypeConverter (Java Platform SE 8 )

public static String printHexBinary(byte[] val)
バイト配列を文字列に変換します。

JAXB は Java 11 から Java SE 標準ライブラリに入っていない

JAXB は Java SE 6 以降の標準ライブラリに入っていた。

JAXB Release Documentation - Frequently Asked Questions

Q: Which version of J2SE does JAXB 2.0 require?
A: Java SE 6 or higher.

JAXB は Java SE 11 以降の標準ライブラリからは削除されている。

Java Platform, Standard Edition Oracle JDK 移行ガイド,リリース11

JDK 11では、Java EEおよびCORBAモジュールが削除されました。これらのモジュールはJDK 9で削除予定の非推奨となりました。

サンプルコード

ソースコード一覧

環境は Java 11 + Gradle 6.1 を想定。

├── build.gradle
└── src
    └── main
        └── java
            └── HexString.java

build.gradle

JAXB を使うため dependencies に javax.xml.bind:jaxb-api:2.3.1 を追加している。

build.gradle
plugins {
  id 'java'
  id 'application'
}

repositories {
  mavenCentral()
}

dependencies {
  // https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api
  implementation 'javax.xml.bind:jaxb-api:2.3.1'
}

application {
  mainClassName = 'HexString'
}

src/main/java/HexString.java

ランダム生成した byte の配列を DatatypeConverter クラスで16進数表記の文字列に変換するサンプルコード。

import java.security.SecureRandom;
import javax.xml.bind.DatatypeConverter;

public class HexString {

  public static void main(String[] args) {
    int num = 0;
    if (args.length > 0) {
      num = Integer.parseInt(args[0]);
    }
    var r = random(num);
    System.out.println("文字列: " + r);
    System.out.println("文字数: " + r.length());
    System.out.println("16進数字表記チェック: " + r.matches("\\p{XDigit}+")); // 正規表現でチェック
  }

  /**
   * ランダムな16進数表記の文字列を返します。
   * @param num 生成する文字数
   * @return ランダムな16進数表記文字列
   */
  public static String random(int num) {
    var random = new SecureRandom();
    byte[] bytes = new byte[num / 2];
    random.nextBytes(bytes);
    return DatatypeConverter.printHexBinary(bytes);
  }
}

実行例

Java 11 (AdoptOpenJDK) + Gradle 6.1 で実行。

$ gradle run --args=32

> Task :run
文字列: A01CCE3E4133D822CCBCA8247353C48F
文字数: 32
16進数字表記チェック: true

BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

DatatypeConverter.printHexBinary の中身

実際の処理は DatatypeConverterImpl クラスの printHexBinary メソッドが担っている。

Maven Repository: javax.xml.bind » jaxb-api » 2.3.1 からダウンロードできる jaxb-api-2.3.1-sources.jar ファイルの中を見ると、 javax/xml/bind/DatatypeConverterImpl.java というファイルがある。

printHexBinary メソッドが byte 配列を16進数表記の文字列に変換している。

private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

public String printHexBinary(byte[] data) {
    StringBuilder r = new StringBuilder(data.length * 2);
    for (byte b : data) {
        r.append(hexCode[(b >> 4) & 0xF]);
        r.append(hexCode[(b & 0xF)]);
    }
    return r.toString();
}

参考資料

1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
niwasawa
迷子になりがちな地図・位置情報系プログラマ。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?