一个实现MD5的简洁的java类

    |     2015年4月29日   |   Java面向对象高级特性   |     0 条评论   |    1713

消息摘要有唯一性和不可逆:同样的输入得到同样的摘要,很难从摘要反推原文。MD5 常被拿来做校验,旧系统里也用来处理用户口令(现代密码存储应使用专门的慢哈希,这里按原文给出一个简洁实现)。

下面这个 StringUtil 把任意字符串编成 32 位十六进制 MD5。

一、实现类

package test;
import java.security.MessageDigest;

public class StringUtil {

    private final static String[] hexDigits = {
        "0", "1", "2", "3", "4", "5", "6", "7",
        "8", "9", "a", "b", "c", "d", "e", "f"
    };

    /**
     * 转换字节数组为 16 进制字串
     * @param b 字节数组
     * @return 16 进制字串
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n = 256 + n;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
        } catch (Exception ex) {
        }
        return resultString;
    }

    public static void main(String[] args) {
        System.err.println(MD5Encode("a"));
    }
}

二、用 RFC 1321 自测

RFC 1321 给出了 Test suite,用来核对实现是否正确:

输入 MD5
""(空串) d41d8cd98f00b204e9800998ecf8427e
"a" 0cc175b9c0f1b6a831c399e269772661
"abc" 900150983cd24fb0d6963f7d28e17f72
"message digest" f96b697d7cb7938d525a2f31aaf161d0
"abcdefghijklmnopqrstuvwxyz" c3fcd3d76192e4007dfb496cca67e13b

主方法打印 MD5Encode("a"),对照表中第二行即可。

一句话总结:MD5 是摘要不是可逆加密:同一原文同一结果,用 RFC 1321 那组向量就能验证自己的实现。

转载请注明来源:一个实现MD5的简洁的java类
本文链接地址:https://ai.zhousir.top/?p=599
回复 取消