哈希函数可以把给定的数据转换成固定长度的无规律数值。转换后的无规律数值可以作为数据摘要应用于各种各样的场景。 哈希值的特征: 1.输出的哈希值数据长度不变; 2.不管输入的数据多小,哈希值的长度仍然相同; 3.如果输入的数据相同,那么输出的哈希值也必定相同(前提是使用同一种算法),即使输入的数据相似,但哪怕它们只有一个比特的差别,那么输出的哈希值也会有很大的差异,即使驶入的两个数据完全不同,输出的哈希值也有可能是相同的,这种情况就是哈希冲突。 4.不可能从哈希值反向的推算出原本的数据,输入和输出不可逆这一点和加密有很大不用; 5.哈希值的计算相对容易。 哈希函数的算法中最具有代表性的是MD5,SHA-1和SHA-2,SHA-2应用较为广泛,而MD5和SHA-1存在安全隐患,不推荐使用,不同的算法计算方式也会有所不同,比如SHA-1需要经过数百次的加法和移位运算才能生成哈希值 对称加密算法:发送发和接收方都是用共同的密钥进行加密和解密,基于这种算法的有:凯撒密码,AES,DES,动态口令等。其中AES的应用最为广泛。 非对称加密算法:加密用的密钥叫做“公钥”,解密用的叫做“私钥”,基于这种算法的有:RAS、椭圆曲线加密算法等。其中RAS的应用最为广泛。通过中途替换公开密钥来窃听数据的攻击方法叫做“中间人攻击”。 SSL协议:混合加密协议,B先生成一对公钥和私钥,将公钥发给A,A将对称密钥用公钥加密之后发给B,A再将用对称密钥加密之后的数据发给B,B先用私钥解密出共享密钥,然后用共享密钥解密出数据。 MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。信息摘要是安全的单向哈希函数,它接收任意大小的数据,输出固定长度的哈希值。 MessageDigest 对象开始被初始化。该对象通过使用update方法处理数据。任何时候都可以调用reset方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用digest方法之一完成哈希计算。

package main.java.com.example.demo;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Tool {
    private static ThreadLocal<MD5Tool> md5ToolThreadLocal = new ThreadLocal<>();
    private MD5Tool() {
    }

    /**
     * 获取一个MD5工具实例
     */
    public static MD5Tool getInstance() {
        if (md5ToolThreadLocal.get() == null) {
            md5ToolThreadLocal.set(new MD5Tool());
        }
        return md5ToolThreadLocal.get();
    }

    /**
     * 通过md5进行加密
     *
     * @param source 要加密的数据
     * @return
     * @throws NoSuchAlgorithmException
     */
    public String getMd5(String source) {
        //1.获取MessageDigest对象
        MessageDigest digest = null;
        try{
            digest = MessageDigest.getInstance("md5");
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        //2.执行加密操作
        byte[] bytes = source.getBytes();

        //在MD5算法这,得到的目标字节数组的特点:长度固定为16
        byte[] targetBytes = digest.digest(bytes);
        //3.声明字符数组
        char[] characters = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        //4.遍历targetBytes
        StringBuilder builder = new StringBuilder();
        for (byte b : targetBytes) {
            //5.取出b的高四位的值
            //先把高四位通过右移操作拽到低四位
            int high = (b >> 4) & 15;
            //6.取出b的低四位的值
            int low = b & 15;
            //7.以high为下标从characters中取出对应的十六进制字符
            char highChar = characters[high];
            //8.以low为下标从characters中取出对应的十六进制字符
            char lowChar = characters[low];
            builder.append(highChar).append(lowChar);
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        String str = "hwgh45yg7gyruhgrtughtrug";
        String md5Str = MD5Tool.getInstance().getMd5(str);
        System.out.println(md5Str);
    }
}