Formatando um Hexa

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 … :frowning: