【发布时间】:2013-03-06 17:08:31
【问题描述】:
我必须解析类似以下“一些文本 ”的内容,我可以在不破坏 40 字节哈希部分的情况下将整个内容读入字符串吗?
问题是哈希不会在那里,所以我不想在阅读时处理它。
编辑:我忘了提到 40 字节散列是 2x20 字节散列,没有编码原始字节。
【问题讨论】:
-
你最后做了什么?
我必须解析类似以下“一些文本 ”的内容,我可以在不破坏 40 字节哈希部分的情况下将整个内容读入字符串吗?
问题是哈希不会在那里,所以我不想在阅读时处理它。
编辑:我忘了提到 40 字节散列是 2x20 字节散列,没有编码原始字节。
【问题讨论】:
从您的输入流中将其作为字节流读取,然后将字符串从流中剥离出来,如下所示:
String s = new String(Arrays.copyOfRange(bytes, 0, bytes.length-40));
然后得到你的字节为:
byte[] hash = Arrays.copyOfRange(bytes, s.length-1, bytes.length-1)
【讨论】:
SHA-1 哈希的长度为 20 字节(160 位)。如果您正在处理 40 个字符的哈希,那么它们可能是哈希的 ASCII 表示,因此仅包含字符 0-9 和 a-f。如果是这种情况,那么您应该能够毫无困难地读取和操作 Java 中的字符串。
【讨论】:
更多细节可能有用,但我认为答案是你应该没问题。
您没有说明 SHA-1 哈希是如何编码的(常见的可能性包括“无”(原始字节)、Base64 和十六进制)。由于 SHA-1 产生一个 20 字节(160 位)的散列,我猜测它将使用十六进制编码,因为这使您提到的 40 字节所需的空间增加了一倍。使用该编码,将使用 2 个字符对哈希中的每个字节进行编码,使用符号 0 到 9 和 A 到 F。这些都是 ASCII 字符,因此您很安全。
Base64 编码也可以工作(尽管可能不是您所问的,因为它将大小增加了大约 1/3,使您的大小远低于 40 个字节),因为 Base64 中使用的每个字符也是 ASCII。
如果直接使用原始字节,您会遇到问题,因为某些值不是有效字符。
【讨论】:
好的,现在你已经澄清了这些是原始字节
不,您不能将其作为字符串读入 Java,您需要将其作为原始字节读取。
【讨论】:
工作代码: 将字节字符串输入转换为在几乎所有字符串编码中都应该安全的十六进制字符。使用我在您的其他问题中发布的代码将十六进制字符解码回原始字节。
/** Lookup table: character for a half-byte */
static final char[] CHAR_FOR_BYTE = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/** Encode byte data as a hex string... hex chars are UPPERCASE */
public static String encode(byte[] data){
if(data == null || data.length==0){
return null;
}
char[] store = new char[data.length*2];
for(int i=0; i<data.length; i++){
final int val = (data[i]&0xFF);
final int charLoc=i<<1;
store[charLoc]=CHAR_FOR_BYTE[val>>>4];
store[charLoc+1]=CHAR_FOR_BYTE[val&0x0F];
}
return new String(store);
}
【讨论】: