Java之消息摘要(MD5)

哈希(Hash)与加密(Encrypt)的区别

哈希是将目标文本转换成固定长度,不可逆的消息摘要
加密是将目标文本转换成具有不同长度,可逆的密文。

选择:
需要还原成明文的选用加密,不需要的话,使用Hash。
密码可以使用哈希, 密码忘记,重置密码。

哈希算法

Hashing 哈希法、散列法。
哈希算法有很多: 常见的有 MD5、SHA1
MD5,全称Message-Digest Algorithm 5, MD5之前有MD2、MD3和MD4
SHA-1 广泛使用在TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被视为MD5的后继者。
SHA-2,包括SHA-224、SHA-256、SHA-384和SHA-512.
SHA-3, 曾被称为Keccak算法。
RIPEMD-160。

Java MessageDigest实现 MD5

MD5计算出128比特位,也就是长度是16的字节数组。
MD5的加密后是长度32的字符串, 长度16的字节数组要产生长度32的字符,则每个字节元素要转换位两个字符。
加密代码如下:

   public static String encrypt(String str) {
        String encryptStr = null;
        try {
            byte[] bytes = MessageDigest.getInstance("MD5").digest(str.getBytes()); //长度16的字节数组
            StringBuffer buffer = new StringBuffer(bytes.length * 2); 
            for (int i = 0; i < bytes.length; i++) { //每个循环产生2个字符
                if (((int) bytes[i] & 0xff) < 0x10) buffer.append("0"); //小于16, 只有一位,则补0
                buffer.append(Long.toString((int) bytes[i] & 0xff, 16)); //int 32bit, 使用&, 高24位置0
            }
            encryptStr = buffer.toString();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return encryptStr;
    }

说明:

  1. MessageDigest.getInstance(“MD5”).digest()用于加密
  2. 因为int是4个字节, 与0xff按位与的目的是高24位置为0.
  3. < 0x10 ,也就是小于10进制16的时候, 就只有一个字符, 此时补一个0。

备注

  1. byte[] bytes = MessageDigest.getInstance(“MD5”).digest(str.getBytes()); 也可以使用以下写法:
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] bytes = md.digest();

Long.toString((int) bytes[i] & 0xff, 16)
也可以使用

buffer.append(Long.toHexString((int) bytes[i] & 0xff));

或是

buffer.append(Integer.toHexString((int) bytes[i] & 0xff));

Long.toString(long i, int radix)
radix - 进制数

        int i = 1;
        String str = Long.toString(i,16);
        Assert.assertTrue(str.equals("1"));
        
        i = 20;
        str = Long.toString(i,16);
        Assert.assertTrue(str.equals("14"));//1*16+4 = 20
        
        i=200;
        str = Long.toString(i,16);
        Assert.assertTrue(str.equals("c8"));//12*16+8 = 20

实例代码:
https://github.com/osxm/jcodef/blob/master/jcodef-func/src/main/java/cn/osxm/jcodef/func/bit/BitTests.java

发布了591 篇原创文章 · 获赞 486 · 访问量 463万+

猜你喜欢

转载自blog.csdn.net/oscar999/article/details/102940066