一.概述

MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。

MessageDigest 对象开始被初始化。该对象通过使用 update()方法处理数据。任何时候都可以调用 reset()方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用digest() 方法之一完成哈希计算。

对于给定数量的更新数据,digest 方法只能被调用一次。在调用 digest 之后,MessageDigest 对象被重新设置成其初始状态。

MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。

MessageDigest 对象开始被初始化。该对象通过使用 update()方法处理数据。任何时候都可以调用 reset()方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用digest() 方法之一完成哈希计算。

对于给定数量的更新数据,digest 方法只能被调用一次。在调用 digest 之后,MessageDigest 对象被重新设置成其初始状态。

1、public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmException
  返回实现指定摘要算法的 MessageDigest 对象。
algorithm - 所请求算法的名称
2、public static MessageDigest getInstance(String algorithm,String provider) throws NoSuchAlgorithmException,NoSuchProviderException
  返回实现指定摘要算法的 MessageDigest 对象。
  algorithm - 所请求算法的名称
  provider - 提供者的名称。
3、public void update(byte[] input)
  使用指定的 byte 数组更新摘要。
4、public byte[] digest()
  通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后,摘要被重置。
5、public static boolean isEqual(byte[] digesta,byte[] digestb)
  比较两个摘要的相等性。做简单的字节比较。

注意:Provider可以通过 java.security.Security.getProviders() 方法获取已注册提供者列表。比较常用的有“SUN”

SUN提供的常用的算法名称有:
MD2
MD5
SHA-1
SHA-256
SHA-384
SHA-512

二、
2.1、创建 MessageDigest 对象
计算信息摘(即散列码)要做的第一步是创建 MessageDigest对象 实例。像所有的引擎类一样,获取某类报文摘要算法(即散列算法,比如MD5)的  MessageDigest 对象的途径是调用 MessageDigest 类中的 getInstance 静态 factory 方法:
    public static MessageDigest getInstance(String algorithm)
注意:算法名不区分大小写。例如,以下所有调用都是相等的:

MessageDigest.getInstance("SHA");
MessageDigest.getInstance("sha");
MessageDigest.getInstance("sHa");

调用程序可选择指定提供者名称,以保证所要求的算法是由已命名提供者实现的:
public static MessageDigest getInstance(String algorithm, String provider);
调用 getInstance 将返回已初始化过的MessageDigest对象。因此,它不需要进一步的初始化。
2.2、向MessageDigest传送要计算的数据
计算数据的摘要的第二步是向已初始化的MessageDigest对象提供传送要计算的数据。这将通过一次或多次调用以下某个 update(更新)方法来完成:

public void update(byte input);
public void update(byte[] input);
public void update(byte[] input, int offset, int len);

2.3、计算摘要
通过调用 update 方法向MessageDigest对象提传送要计算的数据后,你就可以调用以下某个 digest(摘要)方法来计算摘要(即生成散列码):

public byte[] digest();
public byte[] digest(byte[] input);
public int digest(byte[] buf, int offset, int len);

前两个方法返回计算出的摘要。后一个方法把计算出的摘要储存在所提供的 buf 缓冲区中,起点是 offset。len 是 buf 中分配给该摘要的字节数。该方法返回实际存储在 buf 中的字节数。
对第二个接受输入字节数组变量的 digest 方法的调用等价于用指定的输入调用:
    public void update(byte[] input)
,接着调用不带参数的 digest 方法.

三、例子演示

3.1、★ 编程思路:
java.security包中的MessageDigest类提供了计算消息摘要(即生成散列码)的方法,首先生成对象,执行其update( )方法可
以将原始数据传递给该对象,然后执行其digest( )方法即可得到消息摘要。具体步骤如下:
(1)生成MessageDigest对象
MessageDigest m=MessageDigest.getInstance("MD5");
MessageDigest类也是一个工厂类,其构造器是受保护的,不允许
直接使用new MessageDigist( )来创建对象,而必须通过其静态方法getInstance( )生成MessageDigest对象。
其中传入的参数指定计算消息摘要所使用的算法,常用的有"MD5","SHA"等。
(2)传入需要计算的字符串
m.update(x.getBytes("UTF8" ));
分析:x为需要计算的字符串,update传入的参数是字节类型或字节类型数组,对于字符串,需要先使用getBytes( )方法生成字符串数组。
(3)计算消息摘要
byte s[ ]=m.digest( );
分析:执行MessageDigest对象的digest( )方法完成计算,计算的结果通过字节类型的数组返回。
(4)处理计算结果
必要的话可以使用如下代码将计算结果(byte数组)转换为字符串。
 
3.2、示例:
 public class test_md5_1 {

     public static void main(String[] args) {
//待加密的字符串
String myinfo = "abc123";
System.out.println("加密前字符串:"+myinfo);
try {
MessageDigest m1 = MessageDigest.getInstance("MD5");
m1.update(myinfo.getBytes());
byte[] digesta = m1.digest();
System.out.println("本信息摘要是:" + convertToHexString(digesta)); } catch (NoSuchAlgorithmException e) {
System.out.println("非法摘要算法");
}
} /**
* 计算结果(byte数组)转换为字符串
*/
public static String convertToHexString(byte[] digesta) {
String result = "";
for (int i = 0; i < digesta.length; i++) {
//0xff & digesta[i] 取低8位
System.out.println("digesta["+i+"]:"+digesta[i]);
String temp = Integer.toHexString(0xff & digesta[i]); result += temp;
}
return result;
} }

执行结果:

加密前字符串:abc123
digesta[0]:-23
digesta[1]:-102
digesta[2]:24
digesta[3]:-60
digesta[4]:40
digesta[5]:-53
digesta[6]:56
digesta[7]:-43
digesta[8]:-14
digesta[9]:96
digesta[10]:-123
digesta[11]:54
digesta[12]:120
digesta[13]:-110
digesta[14]:46
digesta[15]:3
本信息摘要是:e99a18c428cb38d5f260853678922e3

ps:为什么取低8位?

Integer.toHexString();方法传入的值是int类型的,所以当传入byte的时候就会自动转换成int类型,又由于byte类型只占8位并且int类型占32位,所以会进行补位,如果byte是整数的话没什么影响,因为前面补的是0。但是如果是负数的话就会出现问题了,例如byte b = -112; byte的2进制表示为:1001 0000,java中是以补码的形式进行表示的,这样前面补满22位个1的时候就会出现很多f,所以取低8位。

接着仔细看下输出结果是31位。为什么会少一位,byte数组中有的值可能小于16,所以转换成16进制的时候用1位就可以表示了。这个时候我们应该在前面加上个0。

修改转换字符串的代码:

 /**
* 计算结果(byte数组)转换为字符串
*/
public static String convertToHexString(byte[] digesta) {
String result = "";
for (int i = 0; i < digesta.length; i++) {
//0xff & digesta[i] 取低8位
String temp = Integer.toHexString(0xff & digesta[i]);
if(temp.length()==1){
temp = "0"+temp;
}
result += temp;
}
return result;
}

执行结果:

加密前字符串:abc123
digesta[0]:-23
digesta[1]:-102
digesta[2]:24
digesta[3]:-60
digesta[4]:40
digesta[5]:-53
digesta[6]:56
digesta[7]:-43
digesta[8]:-14
digesta[9]:96
digesta[10]:-123
digesta[11]:54
digesta[12]:120
digesta[13]:-110
digesta[14]:46
digesta[15]:3
本信息摘要是:e99a18c428cb38d5f260853678922e3

上面字节数组补码形式为:

-23|-102|24|-60|40|-53|56|-43|-14|96|-123|54|120|-110|46|3

11101001|10011010|00011000|11000100|00101000|11001011|00111000|11010101|11110010|01100000|10000101|00110110|01111000|0|00101110|0011

MessageDigest简介的更多相关文章

  1. MessageDigest简介(与MD5加密有关)

    参考文章:http://blog.sina.com.cn/s/blog_4f36423201000c1e.html 参考来源:http://blog.csdn.net/hudashi/article/ ...

  2. WebUtils【MD5加密(基于MessageDigest)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 用于MD5加密,主要场景是在调用登录接口时对密码进行MD5加密处理. 效果图 暂不需要 代码分析 基于Java.security.M ...

  3. 一致性hash算法简介与代码实现

    一.简介: 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1.平衡性(Balance) 2.单调性(Monotonicity) 3.分散性(Spread) 4.负 ...

  4. C#中简单调用MD5方法以及MD5简介

    MD5简介:          MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2.M ...

  5. DiskLruCache 硬盘缓存 使用简介

    简介 LruCache只是管理了内存中图片的存储与释放,如果图片从内存中被移除的话,那么又需要从网络上重新加载一次图片,这显然非常耗时.对此,Google又提供了一套硬盘缓存的解决方案:DiskLru ...

  6. MessageDigest类

    public abstract class MessageDigest extends MessageDigestSpi API中的中英文对照简介(未完) java.security.MessageD ...

  7. Java密码体系结构简介:Java Cryptography Architecture (JCA) Reference Guide

    来自Java官方的文档,作备忘使用. 简介: Java平台非常强调安全性,包括语言安全,密码学,公钥基础设施,认证,安全通信和访问控制. JCA是平台的一个主要部分,包含一个“提供者”体系结构和一组用 ...

  8. MessageDigest类实现md5加密

    项目中用到的md5工具类: package com.mall.util; import org.springframework.util.StringUtils; import java.securi ...

  9. LruCache DiskLruCache 缓存 简介 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

随机推荐

  1. ggplot2 legend图例的修改

    ggplot2中的legend包括四个部分: legend.tittle, legend.text, legend.key, legend.backgroud.针对每一部分有四种处理方式: eleme ...

  2. STORM_0004_windows下zookeeper的伪集群的搭建

    -----------------------------------------------------START------------------------------------------ ...

  3. jQuery mobile 前台设计中的css em的使用。

    先贴个网址:http://www.uml.org.cn/html/201207311.asp 大家可以参考一下面这张转换表(body字体为16px时的值) 总结 长篇介绍了一大堆,唯一想告诉大家的是以 ...

  4. iOS - OC RunTime 运行时

    1.运行时的使用 向分类中添加属性 // 包含运行时头文件 #import <objc/runtime.h> /* void objc_setAssociatedObject(id obj ...

  5. Redis实践操作之—— keyspace notification(键空间通知)

    一.需求分析: 设置了生存时间的Key,在过期时能不能有所提示? 如果能对过期Key有个监听,如何对过期Key进行一个回调处理? 如何使用 Redis 来实现定时任务? 二.序言: 本文所说的定时任务 ...

  6. (七)C语言中的void 和void 指针类型

    许多初学者对C中的void 和void 的指针类型不是很了解.因此常常在使用上出现一些错误,本文将告诉大家关于void 和void 指针类型的使用方法及技巧. 1.首先,我们来说说void 的含义: ...

  7. POJ 2418 各种二叉排序树

    题意很明确,统计各个字符串所占总串数的百分比,暴力的话肯定超时,看了书上的题解后发现这题主要是用二叉排序树来做,下面附上n种树的代码. 简单的二叉排序树,不作任何优化(C语言版的): #include ...

  8. [js] 有趣的js面试题,你答对了吗?

    题目1: 回答以下代码,alert的值分别是多少?

  9. 【linux 命令】:查看系统开机,关机时间【转载】

    转载原文:http://www.cnblogs.com/kerrycode/p/3759395.html 看Linux开机关机时间的方法(非常全面) 1: who 命令查看 who -b 查看最后一次 ...

  10. Android布局_布局概述和LinearLayout布局

    一.布局概述: 布局为UI提供了一个可视化的结构,比如对于一个activity或者app widget的UI,你可以用两种方式声明布局: 在XML中声明UI元素 在运行时实例化布局元素(在java代码 ...