MessageDigest简介

本文博客原文

参考文章:http://blog.sina.com.cn/s/blog_4f36423201000c1e.html

一、概述

java.security.MessageDigest类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成散列码。信息摘要是安全的单向哈希函数,它接收任意大小的数据,输出固定长度的哈希值。关于信息摘要和散列码请参照《数字证书简介

MessageDigest 通过其getInstance系列静态函数来进行实例化和初始化。MessageDigest 对象通过使用 update 方法处理数据。任何时候都可以调用 reset 方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用 digest 方法之一完成哈希计算并返回结果。

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

MessageDigest 的实现可随意选择是否实现 Cloneable 接口。客户端应用程可以通过尝试复制和捕获 CloneNotSupportedException 测试可复制性:


MessageDigest md =MessageDigest.getInstance("SHA");

try{

md.update(toChapter1);

MessageDigest tc1 = md.clone();

byte[] toChapter1Digest = tc1.digest();

md.update(toChapter2);

...etc.

}catch(CloneNotSupportedException cnse){

thrownewDigestException("couldn‘t make digest of partial content");

}

注意1:即时给定MessageDigest的实现是不可复制的,则仍然能够通过getInstance方法实例化几个实例计算来同时进行摘要信息的计算。

注意2:由于历史原因,此类是抽象的,是从 MessageDigestSpi 扩展的。应用程序开发人员只应该注意在此 MessageDigest 类中定义的方法;超类中的所有方法是供希望提供自己的信息摘要算法实现的加密服务提供者使用的。

注意3:MessageDigest并不是单实例的。如下代码所示:


try

{

MessageDigest mdTemp1 =MessageDigest.getInstance("MD5");

MessageDigest mdTemp2=MessageDigest.getInstance("MD5");

MessageDigest mdTemp3=MessageDigest.getInstance("MD5");

System.out.println("mdTemp1==mdTemp2?:"+(mdTemp1==mdTemp2));

System.out.println("mdTemp2==mdTemp3?:"+(mdTemp2==mdTemp3));

}catch(NoSuchAlgorithmException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

运行结果


mdTemp1==mdTemp2?:false

mdTemp2==mdTemp3?:false

构造方法摘要
protected MessageDigest(String algorithm)

创建具有指定算法名称的MessageDigest 实例对象。

方法摘要
 Object clone()

如果实现是可复制的,则返回一个副本。

 byte[] digest()

通过执行诸如填充之类的最终操作完成哈希计算。

 byte[] digest(byte[] input)

使用指定的字节数组对摘要进行最后更新,然后完成摘要计算。

 int digest(byte[] buf, int offset, int len)

通过执行诸如填充之类的最终操作完成哈希计算。

 String getAlgorithm()

返回标识算法的独立于实现细节的字符串。

 int getDigestLength()

返回以字节为单位的摘要长度,如果提供程序不支持此操作并且实现是不可复制的,则返回 0。

static MessageDigest getInstance(String algorithm)

生成实现指定摘要算法的 MessageDigest 对象。

static MessageDigest getInstance(String algorithm, Provider provider)

生成实现指定提供程序提供的指定算法的 MessageDigest 对象,如果该算法可从指定的提供程序得到的话。

static MessageDigest getInstance(String algorithm, String provider)

生成实现指定提供程序提供的指定算法的 MessageDigest 对象,如果该算法可从指定的提供程序得到的话。

 Provider getProvider()

返回此信息摘要对象的提供程序。

static boolean isEqual(byte[] digesta, byte[] digestb)

比较两个摘要的相等性。

 void reset()

重置摘要以供再次使用。

 String toString()

返回此信息摘要对象的字符串表示形式。

 void update(byte input)

使用指定的字节更新摘要。

 void update(byte[] input)

使用指定的字节数组更新摘要。

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

使用指定的字节数组,从指定的偏移量开始更新摘要。

 void update(ByteBuffer input)

使用指定的 ByteBuffer 更新摘要。

二、实际实践

2.1、创建 MessageDigest 对象

计算信息摘(即散列码)要做的第一步是创建 MessageDigest对象 实例。像所有的引擎类一样,获取某类报文摘要算法(即散列算法,比如MD5)的  MessageDigest 对象的途径是调用 MessageDigest 类中的 getInstance 静态 factory 方法:


publicstaticMessageDigest getInstance(String algorithm)

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


MessageDigest.getInstance("SHA");

MessageDigest.getInstance("sha");

MessageDigest.getInstance("sHa");

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


publicstaticMessageDigest getInstance(String algorithm,String provider);

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

2.2、向MessageDigest传送要计算的数据

计算数据的摘要的第二步是向已初始化的MessageDigest对象提供传送要计算的数据。这将通过一次或多次调用以下某个 update(更新)方法来完成:


publicvoid update(byte input);

publicvoid update(byte[] input);

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

2.3、计算摘要

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


publicbyte[] digest();

publicbyte[] digest(byte[] input);

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

前两个方法返回计算出的摘要。后一个方法把计算出的摘要储存在所提供的 buf 缓冲区中,起点是 offset。len 是 buf 中分配给该摘要的字节数。该方法返回实际存储在 buf 中的字节数。

对第二个接受输入字节数组变量的 digest 方法的调用等价于用指定的输入调用:


publicvoid 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数组)转换为字符串。


staticString convertToHexString(byte data[]){

StringBuffer strBuffer =newStringBuffer();

for(int i =0; i < data.length; i++){

strBuffer.append(Integer.toHexString(0xff& data[i]));

}

return strBuffer.toString();

}

3.2、示例一

★完整程序如下:


publicclassMessageDigestDemoextendsThread{

publicvoid run(){

String text ="abc";

byte data[]=null;

MessageDigest m;

try{

data = text.getBytes("UTF8");

m =MessageDigest.getInstance("MD5");

m.update(data);

byte resultData[]= m.digest();

System.out.println(convertToHexString(resultData));

}catch(NoSuchAlgorithmException e){

// TODO Auto-generated catch block

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

staticString convertToHexString(byte data[]){

StringBuffer strBuffer =newStringBuffer();

for(int i =0; i < data.length; i++){

strBuffer.append(Integer.toHexString(0xff& data[i]));

}

return strBuffer.toString();

}

}

★运行结果


900150983cd24fb0d6963f7d28e17f72

 3.3、示例二

在这里我们将对计算生成的md5使用 sun.misc.BASE64Encoder进行简单的加密。


publicString md5sumWithEncoder(String text)throwsNoSuchAlgorithmException,

UnsupportedEncodingException{

/*确定计算方法*/

MessageDigest md5=MessageDigest.getInstance("MD5");

BASE64Encoder base64en =new BASE64Encoder();

/*加密后的散列码字符串*/

String strMd5=base64en.encode(md5.digest(text.getBytes("utf-8")));

return strMd5;

}

调用函数


String str="0123456789"

System.out.println(md5sumWithEncoder(str));

输出

eB5eJF1ptWaXm4bijSPyxw==

3.4、示例三

关于此请参考《一点关于计算MD5的封装

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

原文地址:https://www.cnblogs.com/siwnchh/p/10142073.html

时间: 2024-07-29 10:28:54

MessageDigest简介的相关文章

MessageDigest、DigestInputStream、DigestOutputStream简介

MessageDigest MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法.信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值.     MessageDigest 对象开始被初始化.该对象通过使用 update 方法处理数据.任何时候都可以调用 reset 方法重置摘要.一旦所有需要更新的数据都已经被更新了,应该调用 digest 方法之一完成哈希计算.     对于给定数量的更新数据,digest 方法只能被调用一次.在调

Java哈希散列算法简介 - MD5 &amp; SHA-512

Java哈希散列算法简介 - MD5 & SHA-512 在日常的开发工作中,我们常常会碰到这样的一个场景:我们需要有一种可靠的行之有效的方法来检验跟判断数据在传输过程当中的完整性.最常见的一种情况就是当我们传输文件的时候,由于网络故障或者其他的一些因素,可能会出现我们下载下来的文件不完整,这给我们日常的开发和维护带了一些难题:另外的一个较为常用的场景就是:有没有一种行之有效的方法让我们可以很方便的判断服务器上的文件是不是有最新的数据更新,比如我们现在的移动Hybird App开发,我们经常会发

MD5算法 简介

MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD3和MD4发展而来.MD5算法的使用不需要支付任何版权费用. MD5功能 l 输入任意长度的信息,经过处理,输出为128位的信息(数字指纹): l 不同的输入得到的不同的结果(唯一性): l 根据128位的输出结果不可能反推出输入的信息(不可逆): MD5用途 1.防止被篡改: 1)比如发送一个电子文档,发送前,我先得到MD5的输出结果a.然后在对方收到电子文档后,对方也得到一个M

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

MD5简介:          MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2.MD3和MD4发展而来.MD5将任意长度的“字节串”变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法.换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数. MD5算法: 第一

DiskLruCache 硬盘缓存 使用简介

简介 LruCache只是管理了内存中图片的存储与释放,如果图片从内存中被移除的话,那么又需要从网络上重新加载一次图片,这显然非常耗时.对此,Google又提供了一套硬盘缓存的解决方案:DiskLruCache(非Google官方编写,但获得官方认证). 由于DiskLruCache并不是由Google官方编写的,所以这个类并没有被包含在Android API当中,我们需要将这个类从网上下载下来,然后手动添加到项目当中. 下载地址:http://download.csdn.net/detail/

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

一.简介: 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1.平衡性(Balance) 2.单调性(Monotonicity) 3.分散性(Spread) 4.负载(Load) 普通的哈希算法(也称硬哈希)采用简单取模的方式,将机器进行散列,这在cache环境不变的情况下能取得让人满意的结果,但是当cache环境动态变化时,这种静态取模的方式显然就不满足单调性的要求(当增加或减少一台机子时,几乎所有的存储内容都要被重新散列到别的缓冲区中). 一致性哈希算法的

Android网络通讯简介

网络通信应该包含三部分的内容:发送方.接收方.协议栈.发送方和接收方是参与通信的主体,协议栈是发送方和接收方进行通信的契约.按照服务类型,网络通信可分为面向连接和无连接的方式.面向连接是在通信前建立通信链路,而通信结束后释放该链路.无连接的方式则不需要在通信前建立通信连接,这种方式不保证传输的质量. Android提供了多种网络通信的方式,如Java中提供的网络编程,在Android中都提供了支持.Android中常用的网络编程方式如下: 针对TCP/IP协议的Socket和ServerSock

微信红包的架构设计简介

@来源于QCon某高可用架构群整理,整理朱玉华. 背景:有某个朋友在朋友圈咨询微信红包的架构,于是乎有了下面的文字(有误请提出,谢谢) 概况:2014年微信红包使用数据库硬抗整个流量,2015年使用cache抗流量. 微信的金额什么时候算? 答:微信金额是拆的时候实时算出来,不是预先分配的,采用的是纯内存计算,不需要预算空间存储.. 采取实时计算金额的考虑:预算需要占存储,实时效率很高,预算才效率低. 实时性:为什么明明抢到红包,点开后发现没有? 答:2014年的红包一点开就知道金额,分两次操作

JSON 简介

ylbtech-JSON: JSON 简介 JSON:JavaScript Object Notation(JavaScript 对象表示法) JSON是存储和交换文本信息的语法,类似 XML. JSON 比 XML 更小.更快.更易解析. JSON 实例 { "employee":[ {"firstName":"John","lastName":"Doe"}, {"firstName"