Не получается сгенерировать шестнадцатеричную строку из дайджеста SHA256 в Java - PullRequest
0 голосов
/ 01 октября 2010

Не могу понять, где я ошибаюсь:

 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. Я что-то упускаю из-за кодировки?

Ответы [ 3 ]

1 голос
/ 02 октября 2010

Работает как ваш хэш-код, так и шестнадцатеричный код.Я бы поближе посмотрел на содержимое файла, который вы читаете.

Вы также можете написать свой метод шестнадцатеричного кодирования следующим образом:

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 голос
/ 02 октября 2010

Ваш код генерации хеша правильный.Чтобы преобразовать 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();
}
0 голосов
/ 01 октября 2010

A byte значение подписано, и вы используете сохраняющее подпись правое смещение.Это приведет к отрицательным значениям b при вычислении nybble старшего разряда.

Например, рассмотрим, что ваш код делает со значением byte -112 (0x90).При смещении вправо сначала повышается до значения int, 0xFFFFFF90.Затем он сдвигается вправо на 4 бита, сохраняя знак, и становится 0xFFFFFFF9.Затем он возвращается к байту, который просто отбрасывает старшие 24 бита, и 0xF9 (-7 десятичное число) присваивается b.b не больше 9, поэтому результирующий символ (-7 + 48) или ')'.

Сделайте это вместо:

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

Использование byte как локальная переменная не работает на 32- или 64-битной машине.Фактически, приведение к byte является пустой инструкцией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...