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數組,通過取高四位和低四位映射字符,生成一字符串
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章