2010-10-01 39 views
0

消化似乎无法揣摩出我要去错在这里:似乎无法产生十六进制编码字符串从SHA256在Java中

private static String generateHashFromFile(String filePath) { 
    try { 
    final int BUFSZ = 32768; 
    MessageDigest sha = MessageDigest.getInstance("SHA-256"); 
    FileInputStream in = new FileInputStream(filePath); 
    BufferedInputStream is = new BufferedInputStream(in, BUFSZ); 
    byte[] buffer = new byte[BUFSZ]; 
    int num = -1; 
    while((num = is.read(buffer)) != -1) { 
    sha.update(buffer, 0, num); 
    } 
    is.close(); 
    byte[] hash = sha.digest(); 
    return byteArrayToHex(hash); 
    } catch (NoSuchAlgorithmException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } catch (FileNotFoundException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 
    return null; 
} 

private static String byteArrayToHex(byte[] barray) 
{ 
    char[] c = new char[barray.length * 2]; 
    byte b; 
    for (int i = 0; i < barray.length; ++i) 
    { 
     b = ((byte)(barray[i] >> 4)); 
     c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
     b = ((byte)(barray[i] & 0xF)); 
     c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
    } 
    return new String(c); 
} 

即时得到的字符串,如:

")469.76F5941+31E25)6,9,C26)978)4*917180A4C(B7C,E,D+6,7133C705167"

显然不是十六进制!

问题:

  1. 是哈希生成的代码是否正确?
  2. 十六进制编码方法是否正确?
  3. 我错过了关于编码的东西吗?

回答

0

A byte value is signed,and you are using the signed-preserving right-shift。在计算高阶nybble时,这将导致b的负值。

例如,考虑您的代码在byte值-112(0x90)中所做的操作。当右移时,它首先被提升为int的值,0xFFFFFF90。然后它右移4位,保留符号,并变为0xFFFFFFF9。然后将其转换回一个字节,该字节仅丢弃高位24位,并将0xF9(-7十进制)分配给bb不大于9,因此得到的字符是(-7 + 48)或')'。

而是执行此操作:

int hi = (barray[i] & 0xF0) >>> 4, lo = barray[i] & 0xF; 

使用一个byte作为一个局部变量没有做任何好的32位或64位计算机上。事实上,投到byte是一个浪费的指令。

+0

是的,这是问题! – Eno 2010-10-14 22:27:45

1

您的散列生成和十六进制编码代码的作品。我会仔细看看你正在阅读的文件的内容。

你也可以写你的十六进制编码方法,像这样:

public static String byteArrayToHex(byte[] barray) { 
StringBuffer sb = new StringBuffer(); 
for (int i = 0; i < barray.length; i++) { 
    String hex = Integer.toHexString(0xff & barray[i]); 
    if (hex.length() == 1) sb.append('0'); 
    sb.append(hex); 
} 
return sb.toString(); 
} 
1

你的哈希生成的代码是正确的。要将byte[] barray转换成十六进制字符串,您可以简单地执行:

String c = new String(); 
for(short i = 0; i < barray.length; i++) { 
    c += Integer.toString((barray[i] & 255) + 256, 16).substring(1).toUpperCase(); 
} 
相关问题