2010-10-01 4 views
0

peut sembler ne pas savoir où Im va mal ici:ne peut pas sembler générer chaîne codée en hexadécimal de SHA256 en 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); 
} 

Im obtenir des chaînes comme:

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

Clairement pas hexadécimal!

Questions:

  1. est le code de génération de hachage correcte?
  2. La méthode de codage hexadécimal est-elle correcte? Est-ce que je manque quelque chose en ce qui concerne l'encodage?

Répondre

0

Une valeur byte est signée et vous utilisez le décalage vers la droite signé-preserving. Cela se traduira par des valeurs négatives pour b lors du calcul de la valeur Nybble d'ordre élevé. Par exemple, considérons ce que votre code fait avec une valeur byte -112 (0x90). Lors d'un décalage vers la droite, il est d'abord promu à une valeur int, 0xFFFFFF90. Ensuite, il est déplacé à droite de 4 bits, en préservant le signe, et devient 0xFFFFFFF9. Ceci est ensuite renvoyé à un octet, qui supprime simplement les 24 bits de poids fort, et 0xF9 (-7 décimal) est affecté à b. b n'est pas supérieur à 9, le caractère résultant est (-7 + 48), ou ')'.

Pour ce faire, à la place:

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

L'utilisation d'un byte en tant que variable locale ne fait aucun bien sur une machine 32 bits ou 64 bits. En fait, la distribution à byte est une instruction gaspillée.

+0

Oui, c'était le problème! – Eno

1

Votre code de génération de hachage et votre code de codage hexadécimal fonctionnent tous deux. Je regarderais de plus près le contenu du fichier que vous lisez.

Vous pouvez également écrire votre méthode de codage hexadécimal comme ceci:

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

Votre code de génération de hachage est correcte. Pour convertir byte[] barray en une chaîne hexadécimale, vous pouvez simplement faire:

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