Метод BigInteger.toString удаляет ведущие 0
Я пытаюсь генерировать сумму MD5 с помощью MessageDigest.
И у меня есть следующий код.
byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
output = bigInt.toString(16);
Это возвращает не 32 символьную строку, а 31 символьную строку 8611c0b0832bce5a19ceee626a403a7
Ожидаемая строка 08611c0b0832bce5a19ceee626a403a7
На выходе отсутствует ведущее 0.
Я попробовал другой метод
byte[] md5sum = digest.digest();
output = new String(Hex.encodeHex(md5sum));
И результат будет таким, как ожидалось.
Я проверил документ и Integer.toString выполнил преобразование в соответствии с ним
Отображение цифр в символ, предоставляемое Character.forDigit, равно и знак минус добавляется, если это необходимо.
и в Character.forDigit methos
Аргумент цифр действителен, если 0 <= digit < радикс.
Может ли кто-нибудь сказать мне, как два метода отличаются друг от друга и почему вывод 0 удален?
Ответы
Ответ 1
Я бы лично избегал использования BigInteger
для преобразования двоичных данных в текст. Это не совсем то, для чего это нужно, даже если это можно использовать для этого. Там доступно множество кода для преобразования a byte[]
в его шестнадцатеричное представление - например. используя Apache Commons Codec или простой простой метод:
private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
public static String toHex(byte[] data) {
char[] chars = new char[data.length * 2];
for (int i = 0; i < data.length; i++) {
chars[i * 2] = HEX_DIGITS[(data[i] >> 4) & 0xf];
chars[i * 2 + 1] = HEX_DIGITS[data[i] & 0xf];
}
return new String(chars);
}
Ответ 2
Он удаляется, потому что начальный ноль не является значимым, согласно BigInteger
. Нет разницы между 27
и 000000000027
.
Если вам нужна определенная длина, вам придется принудительно ее самостоятельно, с чем-то вроде:
output = ("00000000000000000000000000000000"+output).substring(output.length());
(kludgy, хотя это).
Ответ 3
String.format( "% 064X", новый BigInteger (1, hmac.doFinal(message.getBytes())));
где
- 0 - нулевой ведущий знак
- 64 - длина строки
- X - верхний регистр
Ответ 4
Удаленный нуль заменяется с помощью этого кода:
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(output.getBytes());
byte[] outDigest = digest.digest();
BigInteger outBigInt = new BigInteger(1,outDigest);
output = outBigInt.toString(16);
while (output.length() < 32){
output = "0"+output;
}
Цикл будет учитывать как можно большее количество нулевых нулей