byte []到string并返回byte []

时间:2013-03-19 13:17:52

标签: java string byte

我在解释文件时遇到问题。该文件的构建如下:

  

“名称” - @ - “日期” - @ - “作者” - @ - “签名”

签名是一个字节数组。当我在i中读取文件时,我将其解析为String并将其拆分:

myFileInpuStream.read(fileContent);    
String[] data = new String(fileContent).split("-@-");

如果我查看var fileContent,我会发现字节很好。 但是当我尝试获取签名字节数组时:

byte[] signature=  data[3].getBytes();

有时我会得到错误的63值。我尝试了几个解决方案:

new String(fileContent, "UTF-8")

但没有运气。有人可以帮忙吗? 签名不是固定长度,因此我不能用硬编码...

一些额外信息:

原始签名:

  

[48,45,2,21,0,-123,-3,-5, -115 ,84,-86,26,-124,-112,   75,-10,-1,-56,40,13,-46,6,120,-56,100,2,20,66,-92,-8,   48,-88,101,57,56,20,125,-32,-49,-123,73,96,76,-82,81,   51,69]

filecontent(读取后的var):

  

... 48,45,2,21,0,-123,-3,-5, -115 ,84,-86,26,-124,-112,   75,-10,-1,-56,40,13,-46,6,120,-56,100,2,20,66,-92,-8,   48,-88,101,57,56,20,125,-32,-49,-123,73,96,76,-82,81,   51,69]

签名(在split和getBytes()之后):

  

[48,45,2,21,0,-123,-3,-5, 63 ,84,-86,26,-124,63,75,   -10,-1,-56,40,13,-46,6,120,-56,100,2,20,66,-92,-8,48,-88,101,57,56,20, 125,-32,-49,-123,73,96,76,-82,81,51,69]

4 个答案:

答案 0 :(得分:3)

您无法访问data[4],因为您的表格中有4 String。因此,您可以从0到3访问data

data[0] = name

data[1] = date

data[2] = author

data[3] = signature

解决方案:

byte[] signature = data[3].getBytes();

答案 1 :(得分:1)

编辑:我想我终于明白你在做什么了。

您有四个部分:姓名,日期,作者,签名。名称和作者是字符串,日期是日期,签名是散列或加密的字节数组。您希望将它们作为文本存储在文件中,以-@-分隔。要做到这一点,首先需要将每个转换为有效的字符串。名称和作者已经是字符串。将日期转换为字符串很容易。将字节数组转换为字符串并不容易。

您可以使用 base64 编码将字节数组转换为字符串。使用javax.xml.bind.DatatypeConverter printBase64Binary()进行编码,使用javax.xml.bind.DatatypeConverter parseBase64Binary()进行解码。

例如,如果您有一个名称denBelg,日期2013-03-19,作者Virtlink以及此签名:

30 2D 02 15 00 85 FD FB 8D 54 AA 1A 84 90 4B F6 FF C8 28 0D D2 06 78 C8 64 02 14
 42 A4 F8 30 A8 65 39 38 14 7D E0 CF 85 49 60 4C AE 51 33 45

然后,在签名的连接和base64编码之后,结果字符串变为,例如:

denBelg-@-20130319-@-Virtlink-@-MC0CFQCF/fuNVKoahJBL9v/IKA3SBnjIZAIUQqT4MKhlOTgUfeDPhUlgTK5RM0U=

稍后,当您在-@-上拆分字符串时,您可以解码base64签名部分并返回一个字节数组。

注意名称作者在其名称中包含-@-时,他们可能会搞砸您的代码。例如,如果我将名称设置为den-@-Belg,则代码将失败。


原帖:

Java的String.getBytes()使用字符串的平台默认编码。编码是字符串字符映射到字节值的方式。因此,根据平台,结果字节可能不同。

将编码修复为UTF-8并使用相同的编码进行阅读,您的问题就会消失。

byte[] signature = data[3].getBytes("UTF-8");

String sigdata = new String(signature, "UTF-8");

  

0? - ???ŤK(   ?XD ?? B0e98?}υI`LQ3E

你的例子代表了一些混乱的字符(是加密的还是什么?),但你突出显示的字节显示了问题:

您从字节值 -115 开始。减号表示它是一个高于0x7F的字节值,其字符表示高度依赖于所使用的编码。让我们假设扩展US-ASCII,然后你的字节代表(根据this table)字符ì(带重音)。现在解码时,解码器(取决于您使用的编码)可能无法理解字节值0x8D,而是用问号?表示。请注意,问号是US-ASCII字符 63 ,这就是您的63来自的位置。

因此,确保确保一致地使用您的编码,而不是依赖于系统的默认编码。


此外,永远不要使用字符串编码来解码不代表字符串的字节数组(例如哈希或其他加密内容)。

根据您的评论,您试图读取加密数据(这些是字节)并使用解码器将它们转换为字符串? 永远不会以您期望的任何方式工作。在加密某些内容之后,您将拥有一个字节数组,您应该将存储为。当你读回它们时,你必须通过解密器放置字节以重新获得未加密的字节。只有当那些解密的字节表示字符串时,您才可以使用编码来解码字符串。

答案 2 :(得分:0)

通过手动将这些字节转换为字符串,您可以为自己做额外的工作。你为什么不使用这个类?

// get the file /logs/access.log
Path path = FileSystems.getRoot().getPath("logs", "access.log");
// open it, decoding UTF-8
BufferReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
// read a line of text, properly decoded
String line = reader.readLine();

或者,如果您使用的是Java 6:

BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("/logs/access.log"), "UTF-8"));
String line = reader.readLine();

链接:

答案 3 :(得分:0)

听起来像编码问题。

首先,您需要知道文件使用的编码,并在读取文件时使用它。

其次,你说签名是一个字节数组,但java字符串总是unicode。如果你想要一个不同的编码(我猜你想要ASCII),你需要做getBytes("US-ASCII")

当然,如果您的输入是ascii,那么这可能会导致编码问题,这很奇怪。