前言

  金三银四,又到了求职招聘旺季,很多粉丝也在此期间找到了工作,开始了自己项目实战的首战,最近有几个粉丝小伙伴向我询问MD5加密相关方面的问题,于是我写下这篇博客,希望能帮助到需要的人,作为参加工作即将满一年的我,深知刚刚参加工作确实有很多需要学习的地方,一起加油~

一、MessageDigest 类是什么?

  MessageDigest 类是一个引擎类,全类名是:认识java.security.MessageDigest ,是Java自带的一个类,它是为了提供诸如 SHA1 或 MD5 等密码上安全的报文摘要功能而设计的。密码上安全的报文摘要可接受任意大小的输入(一个字节数组),并产生固定大小的输出,该输出称为一个摘要或散列。摘要具有以下属性:
1、无法通过计算找到两个散列成相同值的报文。
2、摘要不反映任何与输入有关的内容。
使用报文摘要可以生成数据唯一且可靠的标识符。有时它们被称为数据的“数字指纹”。

二、方法介绍

1、getInstance

  返回实现指定摘要算法的MessageDigest对象

/**
 * 返回实现指定摘要算法的MessageDigest对象
 *
 * @param algorithm 请求的算法的名称
 * @param provider 提供者名称
 * @return MessageDigest 指定摘要算法的MessageDigest对象
 * @throws NoSuchAlgorithmException 当指定的请求算法名称不存在时抛出异常
 */
public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmException; 

/**
 * 返回实现指定摘要算法的MessageDigest对象
 *
 * @param algorithm 请求算法的名称
 * @return MessageDigest 指定摘要算法的MessageDigest对象
 * @throws NoSuchAlgorithmException 当指定的请求算法名称不存在时抛出异常
 */
public static MessageDigest getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException;

  Provider可以通过java.security.Security的getProviders() 方法获得已注册的提供者列表
  SUN提供的常用的算法:
    MD2
    MD5
    SHA-1
    SHA-256
    SHA-384
    SHA-512

2、update

  MessageDigest对象在开始时会被初始化,对象通过调用update() 方法处理数据

/**
 * 使用指定的byte数组更新摘要
 *
 * @param input 指定的byte数组
 */
public void update(byte[] input);

3、digest

  一旦所需要更新的数据都已经被更新后,应该调用digest() 方法完成Hash计算。
  对于给定数量的更新数据 ,digest() 方法只能被调用一次.在调用digest() 方法之后,MessageDigest对象被重新设置成初始状态。

/**
 * 通过执行诸如填充之类的最终操作完成Hash计算. 
 * 在调用此方法之后,摘要被重置
 *
 * @return byte[] Hash计算后的byte数组
 */
public byte[] digest();

4、reset

  任何时候都可以调用reset() 方法重置摘要。

5、isEqual

   比较两个摘要的相等性.做简单的字节比较。

/**
 * 比较两个摘要的相等性.做简单的字节比较
 *
 * @param digestA 比较的摘要字节数组A
 * @param digestB 比较的摘要字节数组B
 * @return boolean 是否相等
 */
public static boolean isEqual(byte[] digestA, byte[] digestB);

三、使用步骤

1.创建报文摘要实例

  计算摘要的第一步是创建报文摘要实例。像所有的引擎类一样,获取某类报文摘要算法的 MessageDigest 对象的途径是调用 MessageDigest 类中的 getInstance 静态 factory 方法:

    public static MessageDigest getInstance(String algorithm)

  注意:算法名不区分大小写。例如,以下所有调用都是相等的:

   MessageDigest.getInstance("MD5") 
   MessageDigest.getInstance("md5")  
   MessageDigest.getInstance("Md5")
   MessageDigest.getInstance("mD5")

  调用程序可选择指定提供者名称,以保证所要求的算法是由已命名提供者实现的:

    public static MessageDigest getInstance(String algorithm, String provider)

  调用 getInstance 将返回已初始化过的报文摘要对象。因此,它不需要进一步的初始化。

2.传入需要计算的字符串

m.update(x.getBytes(“UTF8” ));

  分析:x为需要计算的字符串,update传入的参数是字节类型或字节类型数组,对于字符串,需要先使用getBytes( )方法生成字符串数组。

3.计算消息摘要

byte s[ ]=m.digest( );

  分析:执行MessageDigest对象的digest( )方法完成计算,计算的结果通过字节类型的数组返回。

4.处理计算结果

  必要的话可以使用如下代码将计算结果s转换为字符串。

 StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }

            re_md5 = buf.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }

四、MD5工具类

1.MessageDigest实现对字符串的MD5加密算法

/**
 * 将字符串转换为MD5
 */
 public class ParseMD5 {
 	public static String parseStrToMd5L32(String str) {
 		// 将字符串转换为32位小写MD5 
 		String reStr = null;
 		try {
 			MessageDigest md5 = MessageDigest.getInstance("MD5");
 			byte[] bytes = md5.digest(str.getBytes());
 			StringBuffer stringBuffer = new StringBuffer();
 			for (byte b : bytes) {
 				int bt = b&0xff;
 				if (bt < 16) {
 					stringBuffer.append(0);
 				}
 				stringBuffer.append(Integer.toHexString(bt));
 			}
 			reStr = stringBuffer.toString();
 		} catch (NoSuchAlgorithmException e) {
 			e.printStackTrace();
 		}
 		return reStr;
 	}

	// 将字符串转换为32位大写的MD5
	public static String parseStrToMd5U32(String str) {
		String reStr = parseStrToMd5L32(str);
		if (reStr != null) {
			reStr = reStr.toUpperCase();
		}
		return resStr;
	}

	// 将字符串转换为16位小写的MD5
	public static String parseStrToMd5L16(String str) {
		String reStr = paseStrToMd5L32(str);
		if (reStr != null) {
			reStr = reStr.subString(8, 24);
		}
		return reStr;
	}

	// 将字符串转换为16位大写的MD5
	public static String parseStrToMd5U16(String str) {
		String reStr = parseStrToMd5L32(str);
		if (reStr != null) {
			reStr = reStr.toUpperCase().subString(8, 24);
		}
		return reStr;
	}
 }

2.MessageDigest实现对文本的MD5加密算法

public class MD5Util {
	// 将文本转换为32位小写的MD5
	public static String textToMd5L32(String plainText) {
		String result = null;
		// 判断需要转换的文本是否为空
		if (StringUtils.isBlank(plainText)) {
			return null;
		}
		try {
			// 进行实例化和初始化
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			// 得到一个操作系统默认的字节编码格式的字节数组
			byte[] byteInput = plainText.getBytes();
			// 对得到的字节数组进行处理
			md5.update(byteInput);
			// 进行Hash计算并得到返回结果
			byte[] btResult = md5.digest();
			// 得到进行Hash计算后数据的长度
			StringBuffer stringBuffer = new StringBuffer();
			for (byte b : btResult) {
				int bt = b&0xff;
				if (bt < 16) {
					stringBuffer.append(0);
				}
				stringBuffer.append(Integer.toHexString(bt));
			}
			reStr = stringBuffer.toString();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return reStr;
	}

	// 将文本转换为32位大写的MD5
	public static String textToMd5U32(String plainText) {
		if (StringUtils.isBlank(plainText)) {
			return null;
		}
		String result = textToMd5L32(plainText);
		result = result.toUpperCase();
		return result;
	}	
}

3.简化写法

public class MD5 {

    public static String encryption(String plainText1) {
        String plainText=plainText1+"1@boduojiayuan#$@";
        String re_md5 = new String();
        try {
           //  返回实现指定摘要算法的MessageDigest对象
            MessageDigest md = MessageDigest.getInstance("MD5");
           //  对象通过调用update() 方法处理数据
            md.update(plainText.getBytes());
            // 调用digest() 方法完成Hash计算
            byte b[] = md.digest();
            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
			// 将计算结果s转换为字符串
            re_md5 = buf.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return re_md5;
    }

五、总结

成为一个小胖子,没事摸摸小肚子~

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐