В Java, как я могу преобразовать байтовый массив в строку шестнадцатеричных цифр, сохраняя ведущие нули? - PullRequest
156 голосов
/ 01 декабря 2008

Я работаю с примером кода Java для создания хэшей md5. Одна часть преобразует результаты из байтов в строку шестнадцатеричных цифр:

byte messageDigest[] = algorithm.digest();     
StringBuffer hexString = new StringBuffer();
for (int i=0;i<messageDigest.length;i++) {
    hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
    }

Однако, это не совсем работает, поскольку toHexString, по-видимому, сбрасывает начальные нули. Итак, как проще всего перейти от байтового массива к шестнадцатеричной строке, которая поддерживает ведущие нули?

Ответы [ 28 ]

0 голосов
/ 23 декабря 2018

Или вы можете сделать это:

byte[] digest = algorithm.digest();
StringBuilder byteContet = new StringBuilder();
for(byte b: digest){
 byteContent = String.format("%02x",b);
 byteContent.append(byteContent);
}

Это коротко, просто и в основном просто изменение формата.

0 голосов
/ 27 января 2012

ИМХО все приведенные выше решения, которые предоставляют фрагменты для удаления начальных нулей, неверны.

byte messageDigest[] = algorithm.digest();
for (int i = 0; i < messageDigest.length; i++) {
    hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
}    

Согласно этому фрагменту, 8 битов берутся из байтового массива в итерация, преобразованная в целое число (поскольку функция Integer.toHexString принимает int как аргумент), а затем это целое число преобразуется в соответствующий хэш значение. Так, например, если у вас есть 00000001 00000001 в двоичном, в соответствии с код, переменная hexString будет иметь значение 0x11 в качестве шестнадцатеричного значения, тогда как правильное значение должно быть 0x0101. Таким образом, при расчете MD5 мы можем получить хэши длиной <32 байта (из-за пропущенных нулей), которые могут не удовлетворять криптографически уникальные свойства, которые делает хеш MD5. </p>

Решением проблемы является замена приведенного выше фрагмента кода на следующий фрагмент:

byte messageDigest[] = algorithm.digest();
for (int i = 0; i < messageDigest.length; i++) {
    int temp=0xFF & messageDigest[i];
    String s=Integer.toHexString(temp);
    if(temp<=0x0F){
        s="0"+s;
    }
    hexString.append(s);
}
0 голосов
/ 17 февраля 2016

Я удивлен, что никто не придумал следующее решение:

StringWriter sw = new StringWriter();
com.sun.corba.se.impl.orbutil.HexOutputStream hex = new com.sun.corba.se.impl.orbutil.HexOutputStream(sw);
hex.write(byteArray);
System.out.println(sw.toString());
0 голосов
/ 24 апреля 2014

Это ошибочное решение? (Android Java)

    // Create MD5 Hash
    MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
    digest.update(s.getBytes());
    byte[] md5sum = digest.digest();
    BigInteger bigInt = new BigInteger(1, md5sum);
    String stringMD5 = bigInt.toString(16);
    // Fill to 32 chars
    stringMD5 = String.format("%32s", stringMD5).replace(' ', '0');
    return stringMD5;

Так что в основном он заменяет пробелы на 0.

0 голосов
/ 29 августа 2013

мой вариант

    StringBuilder builder = new StringBuilder();
    for (byte b : bytes)
    {
        builder.append(Character.forDigit(b/16, 16));
        builder.append(Character.forDigit(b % 16, 16));
    }
    System.out.println(builder.toString());

у меня это работает.

0 голосов
/ 12 июня 2013

А как можно снова преобразовать обратно из ascii в байтовый массив?

Я следовал следующему коду для преобразования в ascii, данный Jemenake.

public static String toHexString(byte[] bytes) {
    char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for ( int j = 0; j < bytes.length; j++ ) {
        v = bytes[j] & 0xFF;
        hexChars[j*2] = hexArray[v/16];
        hexChars[j*2 + 1] = hexArray[v%16];
    }
    return new String(hexChars);
}
0 голосов
/ 31 января 2013

Это даст строку длиной в два символа для байта.

public String toString(byte b){
    final char[] Hex = new String("0123456789ABCDEF").toCharArray();
    return  "0x"+ Hex[(b & 0xF0) >> 4]+ Hex[(b & 0x0F)];
}
0 голосов
/ 27 августа 2012

Это также эквивалентно, но более сжато, используя утилиту Apache HexBin , где код уменьшается до

HexBin.encode(messageDigest).toLowerCase();
...