MassageDigest介绍与实践

看看jdk怎么说

This MessageDigest class provides applications the functionality of a
message digest algorithm, such as SHA-1 or SHA-256.
Message digests are secure one-way hash functions that take arbitrary-sized
data and output a fixed-length hash value.

实话实说,我的英语要是再好点,我就能很少用去看别人写的博客了,因为这段注释已经写的很清楚了,所以,这个英文的注释要常看,希望有一天能很顺畅的都这些注释。

这个类提供了一些消息摘要算法,例如SHA-1,SHA-256.它是一个安全的单向哈希函数,能把不定长度的
数据转化成固定长度的hash值

用法

通过查看注释可以比较清晰的理解该类的核心方法

  • update(byte) 通过这个函数来处理数据
  • reset() 通过这个函数来重置
  • digest 在经过可能多次update后,一定最后要调用这个函数来结束整个运算过程

下面是jdk中给的使用范例

 MessageDigest md = MessageDigest.getInstance("SHA-256");
 
  try {
      md.update(toChapter1);
      MessageDigest tc1 = md.clone();
      byte[] toChapter1Digest = tc1.digest();
      md.update(toChapter2);
      ...etc.
  } catch (CloneNotSupportedException cnse) {
      throw new DigestException("couldn't make digest of partial content");
  }

工具类封装

以下工具类来之西北野狼的博客

package com.company;

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) throws NoSuchAlgorithmException {
        //1.获取MessageDigest对象
        MessageDigest digest = MessageDigest.getInstance("md5");

        //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();
    }

}

以上代码有两点比较有意思

  1. 用ThreadLocal来封装实例,避免了线程安全问题
  2. 对函数运算结果的一个byte数组,通过取高四位和低四位映射字符,生成一字符串
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章