在java中以字节数组存储数据

在java中以字节数组存储数据,java,arrays,types,byte,byte-shifting,Java,Arrays,Types,Byte,Byte Shifting,我试图将“password”之类的字符串转换为十六进制值,然后将其放入一个长数组中,循环工作正常,直到达到值“6F”(o char的十六进制值),然后出现异常java.lang.NumberFormatException String password=“password”; 字符数组[]=password.toCharArray(); int指数=0; for(字符c:数组){ 字符串十六进制=(Integer.toHexString((int)c)); 数据[索引]=Long.parseLo

我试图将“password”之类的字符串转换为十六进制值,然后将其放入一个长数组中,循环工作正常,直到达到值“6F”(o char的十六进制值),然后出现异常
java.lang.NumberFormatException

String password=“password”;
字符数组[]=password.toCharArray();
int指数=0;
for(字符c:数组){
字符串十六进制=(Integer.toHexString((int)c));
数据[索引]=Long.parseLong(十六进制);
索引++;
}

当6F大于1字节时,如何在字节数组中存储6F值?。请在这方面帮助我。parseLong解析十进制数。它将字符串“10”转换为数字10。如果输入为十六进制,则不正确-字符串“10”应转换为数字16。解决方法是使用
Long.parseLong(字符串输入,整数基数)
方法。您想要的基数是16,尽管将其写成
0x10
可能更具可读性——这对编译器来说是一样的,纯粹是个人风格的选择。因此,
Long.parseLong(十六进制,0x10)
就是您想要的

请注意,实际上
char
中的数字从0到65535不等,不能用字节表示。实际上,您必须记下一个标记,密码中不能包含任何非ASCII字符(因此不能包含umlauts、雪人、表情符号、有趣的引号等)

如果未选中此项,
Integer.tohextString((int)c)
将变成类似于
16F
或更糟的字符(3到4个字符),也可能变成单个字符

更一般地说,从
charc
转换为十六进制字符串,然后将十六进制字符串解析为数字是完全没有意义的。它把15变成F,然后把F变成15。如果你只想把一个字符塞进一个字节:
data[index++]=(byte)c
是您所需要的全部-这是您在
for
循环中唯一需要的行

但是,请注意:

你真的不该这么做! 您要做的是将字符数据转换为字节数组。这其实并不简单——可能只有256个字节,而且人们已经发明了更多的字符。从字面上看,数十万个

因此,要将字符转换为字节或将字符转换为字节,必须应用编码。编码具有各种各样的特性。然而,最常用的编码是“UTF-8”。它表示每个unicode符号,并且具有一个有趣的特性,即基本ASCII字符看起来完全相同。然而,它也有缺点,任何给定的字符都会被涂抹成1、2、3甚至4个字节,这取决于它是什么字符。幸运的是,java有很多用于此的工具,因此,您无需在意。你真正想要的是:

byte[] data = password.getBytes(StandardCharsets.UTF8);
这要求字符串使用UTF8编码将自身转换为字节数组。这意味着“password”变成了序列'112971151151191111111100',这无疑是您想要的,但您也可以将其作为密码,例如,
außgescheignet☃,这也有效-它已转换为字节,您可以返回到您的雪人启用密码:

String in = "außgescheignet ☃";
byte[] data = in.getBytes(StandardCharsets.UTF8);
String andBackAgain = new String(data, StandardCharsets.UTF8);
assert in.equals(andBackAgain); // true
如果将其粘贴到源文件中,请确保将其保存在任何文本编辑器中,作为UTF8执行此操作,并且javac也以这种方式编译它(javac有一个-encoding参数来强制执行此操作)


如果您认为这将导致您发送到的内容出现问题,并且您希望将其限制为以美国为中心的人所称的“普通”字符,那么您需要与此处显示的代码完全相同的代码,但使用
StandardCharsets.ASCII
。然后,如果该行(
password.getBytes(StandardCharsets.ASCII)
)包含非ASCII字符,则该行将消除错误。这是一件好事:您的基础架构无法正确处理它,我们只是在这个假设练习中假设了这一点。在过程的早期,在相关行上抛出异常正是您想要的。

如果您读取Javadoc,请尝试使用正确的方法读取字符串中的字符,这些字符必须都是十进制数字,因此我可以在字节值中存储6F这样的值吗?@scarywombatt上述代码甚至不处理字节。参见公共静态最终字节最大值,一个保持字节最大值的常数,27-1。如果您查看asci表,您会看到
o
->
6F
->
dec 111
可能会看到以下内容:注意:
char
也是一个-可以在算术中使用,只需转换为其他类型
long l=(long)c