Método toMD5 (feature do C# 3.0)

Olá

O Chun no excelente tópico criado pelo bush sobre o Java 7, colocou um link para algumas das novidades do C# 3.0 na mensagem http://www.guj.com.br/posts/list/30/41027.java#220697

Ele não gostou das novidades mostradas em New language features in C# 3.0. Mas apesar da maioria ser de pouca utilidade, eu até que gostei de alguma coisa. Minha curiosidade se voltou para a possibilidade de adicionar métodos estáticos às classes default como String:

Ora, extender a classe String já foi o sonho de alguns programadores Java dentro da própria Sun. Como isto não é possível, escrevi uma classe utilitária que que tem um método estático toMD5()

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.io.UnsupportedEncodingException;   // Por causa do Java 5

public class Conversion {
    
    // Converte uma String em outra codificada em MD5
    public static String toMD5(String s) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");

            // Pegar o Charset
            String userEnc = System.getProperty("user.encoding");

            Charset cs = null;
            if (userEnc == null) {
                cs = Charset.defaultCharset();
            } else {
                if (Charset.isSupported(userEnc)) {
                    try {
                        cs = Charset.forName(userEnc); 
                    } catch (IllegalCharsetNameException icne) {
                        return null;
                    } catch (UnsupportedCharsetException uce) {
                        return null;
                    }
                } else {  
                    return null;
                }
            }

            // Se fosse Java6 bastava fazer:
            // md.update(s.getBytes(cs));        
            
            byte[] tmp = null;
            try {
                tmp = s.getBytes(cs.name());               
            } catch (UnsupportedEncodingException uee) {
               return null;
            }
            md.update(tmp);
         
            return byteArrayToHexString(md.digest());

        } catch (NoSuchAlgorithmException nsae) {
            return null;
        }
    }

    private static final String[] hexDigits = {"0","1","2","3","4","5","6","7",
                                         "8","9","a","b","c","d","e","f"};
    // Converte um byte para uma String hexadecimal
    public static String byteToHexString(byte b) {
        int n = b;
        if(n &lt 0) 
            n = 256 + n;
        int d1 = n / 16;
        int d2 = n % 16; 
        return hexDigits[d1] + hexDigits[d2];
    }

    // Converte um array de bytes em uma String hexadecimal
    public static String byteArrayToHexString(byte[] b) {
        String result = "";
        for(int i=0;i<b.length;++i)
            result += byteToHexString(b[i]); 
        return result;
    }

    // Driver para teste
    public static void main(String[] args) {
        if (args.length == 1) {
            System.out.println("Entrada: [" + args[0] + "]\nSaída  : [" + toMD5(args[0]) + "]");
        } else {
            System.out.println("Uso: java -Duser.encoding=enc Conversion String" + 
                "\n     Onde enc = opcao de encoding como por exemplo: ISO-8859-1, UTF-8, etc.");
        }
    }
}

Com Java deu um pouquinho mais de trabalho do que com o futuro C# 3.0. Apesar de eu ter complicado a questão do encoding, (Thingol, grite se codifiquei complicado demais), na minha opinião o código Java ficou mais bonitinho. Principalmente quando se usa o Java 6 onde é possível chamar getBytes() com um Charset como parâmetro. Para usar Java 6 descomentamos 2 instruções e comentamos o trecho que vai desde byte[] tmp = null; até md.update(tmp);

PS: O uso de Charset é para o programa funcionar igual em vários character-encoding schemes caso o usuário entre uma String com caracteres fora dos 95 caracteres ASCII imprimíveis (32-126). Não sei se o ToMD5 do C# tem este cuidado.

[]s
Luca (brincando com o Chun) :lol: