Preciso formatar cada resultado (no caso de uma chave MD5) num String Hexa. O caso é que o Integer.toHexString() devolve o valor mas não formatado em duas casas. Então, um valor menor a 16, como “5” devolver “5” e não “05”.
Implementei um workaround (tá bom, fiz nas coxas) que ficou assim:
String sval = Integer.toString((byteDigest[idx] & 0xff),16);
if(sval.length() == 1)
sval = "0" + sval;
sendo byteDigest[idx] um byte de um vetor de bytes, é claro.
Como NumberFormat ou DecimalFormat não aceitam valores não numéricos, e o Integer.toHexString() também faz a mesma coisa que o toString com ‘radix’, como formatar um hexa sempre com dois algarismos ?
Alguém conhece outra solução mais bela que o meu workaround ?
8)
String sval = (Integer.toString((byteDigest[idx] & 0xff),16).length() ==1)?"0"+Integer.toString((byteDigest[idx] & 0xff),16):Integer.toString((byteDigest[idx] & 0xff),16);
Brincadeira!!
Acho que a sua solução é a ideal.
Eu costumo fazer o seguinte (já que sou meio neurótico quanto a desempenho):
private static final char[] hexDigits = "0123456789abcdef".toCharArray();
public static String toHex (byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; ++i) {
sb.append (hexDigits [(bytes[i] >> 4) & 0x0F]).append (hexDigits [bytes[i] & 0x0F]);
}
return sb.toString();
}
Uma outra forma que às vezes uso é a seguinte: eu sei que se eu fizer um “OR” de um byte com 0x100 e converter para hexa, vou ter alguma coisa entre “100” e “1FF”. Portanto, basta pegar os últimos 2 dígitos:
byte b = 0x0A;
System.out.println (Integer.toHexString ((b & 0xFF) | 0x100).substring(1));
deve imprimir 0a. ou 0A (não sei se o Java põe em minúscula ou em maiúscula).
E ainda existe uma das melhores coisas do java5: printf!
Pra usá-lo será necessário um PrintWriter, que pode ser feito assim:
// antes do for que muda idx
ByteArrayOutputStream stream = new ByteArrayOutputStream();
PrintStream hexa = new PrintStream(stream);
// durante o seu for do idx
hexa.printf("%02X", byteDigest[idx] & 0xff);
// resultado em String
stream.toString();
Em C normalmente uso o sprintf ("%02X"), em vez de usar essa maluquice de “Integer.toHexString ((b & 0xFF) | 0x100).substring(1)” que mostrei acima. Nem tinha lembrado disso (embora, como disse, eu seja muito neurótico com desempenho - só iria usar String.format ("%02X") se fosse alguma coisa que fosse pouco usada.
[quote=dudaskank]E ainda existe uma das melhores coisas do java5: printf!
[/quote]
Pois é, também estava esperando faz tempo printf e varargs !
Mas desta vez não posso usar o Tiger não …