如何在 Java 中初始化字节数组?

我必须在 Java 中以字节数组的形式存储一些常量值(UUID) ,我想知道初始化这些静态数组的最佳方法是什么。我现在就是这么做的但我觉得肯定有更好的办法。

private static final byte[] CDRIVES = new byte[] { (byte)0xe0, 0x4f, (byte)0xd0,
0x20, (byte)0xea, 0x3a, 0x69, 0x10, (byte)0xa2, (byte)0xd8, 0x08, 0x00, 0x2b,
0x30, 0x30, (byte)0x9d };
private static final byte[] CMYDOCS = new byte[] { (byte)0xba, (byte)0x8a, 0x0d,
0x45, 0x25, (byte)0xad, (byte)0xd0, 0x11, (byte)0x98, (byte)0xa8, 0x08, 0x00,
0x36, 0x1b, 0x11, 0x03 };
private static final byte[] IEFRAME = new byte[] { (byte)0x80, 0x53, 0x1c,
(byte)0x87, (byte)0xa0, 0x42, 0x69, 0x10, (byte)0xa2, (byte)0xea, 0x08,
0x00, 0x2b, 0x30, 0x30, (byte)0x9d };
...
and so on

有没有什么东西我可以用,可能效率较低,但会看起来更干净? 例如:

private static final byte[] CDRIVES =
new byte[] { "0xe04fd020ea3a6910a2d808002b30309d" };
845265 次浏览

您可以使用 JavaUUID 类来存储这些值,而不是字节数组:

UUID


public UUID(long mostSigBits,
long leastSigBits)

使用指定的数据构造新的 UUID。MostSigBits 用于 UUID 的最高有效64位,leastSigBits 成为 UUID 的最低有效64位。

就干净的进程而言,您可以使用 ByteArrayOutputStream对象..。

ByteArrayOutputStream bObj = new ByteArrayOutputStream();
bObj.reset();

//使用

bObj.write(byte value)

//完成后,可以使用

CDRIVES = bObj.toByteArray();

//也可以对 CMYDOCS 和 IEFRAME 重复类似的过程,

注意 如果你真的使用小数组,这不是一个有效的解决方案。

可以使用实用程序函数将熟悉的六进制字符串转换为 byte[]。 当用于定义 final static常量时,性能开销是无关紧要的。

从 Java 17开始

现在有 java.util.HexFormat让你做

byte[] CDRIVES = HexFormat.of().parseHex("e04fd020ea3a6910a2d808002b30309d");

这个实用工具类允许你指定一种格式,当你发现其他格式更容易阅读或者当你从引用源复制粘贴时,这种格式很方便:

byte[] CDRIVES = HexFormat.ofDelimiter(":")
.parseHex("e0:4f:d0:20:ea:3a:69:10:a2:d8:08:00:2b:30:30:9d");

在 Java17之前

我建议您使用 使用 Java 将十六进制转储的字符串表示转换为字节数组?中 Dave L 定义的函数

byte[] CDRIVES = hexStringToByteArray("e04fd020ea3a6910a2d808002b30309d");

我把它插入到这里以获得最大的可读性:

public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}

在 Java6中,有一个方法可以完全满足您的需要:

private static final byte[] CDRIVES = javax.xml.bind.DatatypeConverter.parseHexBinary("e04fd020ea3a6910a2d808002b30309d")

或者你可以使用 谷歌番石榴:

import com.google.common.io.BaseEncoding;
private static final byte[] CDRIVES = BaseEncoding.base16().lowerCase().decode("E04FD020ea3a6910a2d808002b30309d".toLowerCase());

当您使用小数组时,Guava 方法是过度使用的。但是 Guava 也有可以解析输入流的版本。在处理大的十六进制输入时,这是一个很好的特性。

byte[] myvar = "Any String you want".getBytes();

字符串可以转义为提供任何字符:

byte[] CDRIVES = "\u00e0\u004f\u00d0\u0020\u00ea\u003a\u0069\u0010\u00a2\u00d8\u0008\u0000\u002b\u0030\u0030\u009d".getBytes();

在这种情况下,我的首选方案是使用 org.apache.commons.codec.binary.Hex,它具有在 Stringy 十六进制和二进制之间进行转换的有用 API。例如:

  1. 如果数组中有非十六进制字符,或者有奇数个字符,则抛出 DecoderException

  2. Hex.encodeHex(byte[] data)与上面的解码方法相对应,并产生 char[]

  3. byte数组转换回 StringHex.encodeHexString(byte[] data)

用法: Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())

private static final int[] CDRIVES = new int[] {0xe0, 0xf4, ...};

访问后转换为字节。

没有库、返回动态长度、无符号整数解释(不是二的补充)的解决方案

    public static byte[] numToBytes(int num){
if(num == 0){
return new byte[]{};
}else if(num < 256){
return new byte[]{ (byte)(num) };
}else if(num < 65536){
return new byte[]{ (byte)(num >>> 8),(byte)num };
}else if(num < 16777216){
return new byte[]{ (byte)(num >>> 16),(byte)(num >>> 8),(byte)num };
}else{ // up to 2,147,483,647
return new byte[]{ (byte)(num >>> 24),(byte)(num >>> 16),(byte)(num >>> 8),(byte)num };
}
}

你可以使用这个效用函数:

public static byte[] fromHexString(String src) {
byte[] biBytes = new BigInteger("10" + src.replaceAll("\\s", ""), 16).toByteArray();
return Arrays.copyOfRange(biBytes, 1, biBytes.length);
}

与 Denys Séguret 和 stefan.schweschke 的变体不同,它允许在输入字符串中插入分隔符号(空格、制表符等) ,使其更具可读性。

用法示例:

private static final byte[] CDRIVES
= fromHexString("e0 4f d0 20 ea 3a 69 10 a2 d8 08 00 2b 30 30 9d");
private static final byte[] CMYDOCS
= fromHexString("BA8A0D4525ADD01198A80800361B1103");
private static final byte[] IEFRAME
= fromHexString("80531c87 a0426910 a2ea0800 2b30309d");

最小的内部类型是 Char,在编译时可以用 没签名十六进制编号分配,如

private static final char[] CDRIVES_char = new char[] {0xe0, 0xf4, ...};

为了拥有等效的字节数组,可以将转换部署为

public static byte[] charToByteArray(char[] x)
{
final byte[] res = new byte[x.length];
for (int i = 0; i < x.length; i++)
{
res[i] = (byte) x[i];
}
return res;
}


public static byte[][] charToByteArray(char[][] x)
{
final byte[][] res = new byte[x.length][];
for (int i = 0; i < x.length; i++)
{
res[i] = charToByteArray(x[i]);
}
return res;
}

你可以用充气城堡套餐,

玛文进口公司,

  <dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>

Java 代码,

byte[] CDRIVES = Hex.decode("e04fd020ea3a6910a2d808002b30309d");