java MD5 并发
Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。该算法的文件号为RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992)。
查看MessageDigest源码
public void update(byte[] input) {
engineUpdate(input, 0, input.length);
state = IN_PROGRESS;
}
可以看到这里调用了engineUpdate方法,此方法进行一个更新操作。
然后state属性的状态就被改变了,表明当前计算正在处理过程中。
state默认属性
private int state = INITIAL;
然后需要调用MessageDigest.digest()方法计算哈希值
public byte[] digest() {
/* Resetting is the responsibility of implementors. */
byte[] result = engineDigest();
state = INITIAL;
return result;
}
到这里已经完成了MD5值的计算,state属性恢复初始状态,如果想要重用MessageDigest对象,还需要调用MessageDigest.reset()方法进行重置,以免这次计算数据会对下一次的计算造成影响,从而导致计算结果错误。
而我所遇到的问题就是,在MessageDigest在多线程的环境下,Thread-1的计算还没有完成的情况下,Thread-2又开始使用该MessageDigest对象进行下一次的计算,Thread-2修改了MessageDigest的状态,Thread-1使用被修改过后的MessageDigest进行计算,从而导致了计算结果错误。
解决方案有两个:
1、加锁来共享同一个MessageDigest;
public class MD5 {
private static final byte[] ToHex_ =
{ '0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f'
};
private MessageDigest md5_ = null;
static private MessageDigest Md5_;
static
{
try { Md5_ = MessageDigest.getInstance("MD5");} // MD5 is supported
catch ( NoSuchAlgorithmException e ) {}; // safe to swallow
};
public MD5()
{
try { md5_ = MessageDigest.getInstance("MD5");} // MD5 is supported
catch ( NoSuchAlgorithmException e ) {}; // safe to swallow
}
/**
*
*/
public static synchronized String Digest(byte[] dataToHash)
{
Md5_.update(dataToHash, 0, dataToHash.length);
return HexStringFromBytes( Md5_.digest() );
}
/**
* Non-threadsafe MD5 digest (hashing) function
*/
public String digest(byte[] dataToHash)
{
md5_.update(dataToHash, 0, dataToHash.length);
return HexStringFromBytes( md5_.digest() );
}
private static String HexStringFromBytes(byte[] b)
{
byte [] hex_bytes = new byte[ b.length * 2 ];
int i,j=0;
for (i=0; i < b.length; i++)
{
hex_bytes[j] = ToHex_[ ( b[i] & 0xF0 ) >> 4 ] ;
hex_bytes[j+1] = ToHex_[ b[i] & 0xF ];
j+=2;
}
return new String( hex_bytes );
}
}
2、每次新创建一个MessageDigest;
class MD5_test {
public final static String MD5(String s) {
char hexDigits[] = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
'a' , 'b' , 'c' , 'd' , 'e' , 'f' };
try {
byte [] strTemp = s.getBytes();
MessageDigest mdTemp = MessageDigest.getInstance("MD5" );
mdTemp.update(strTemp);
byte [] md = mdTemp.digest();
int j = md.length;
char str[] = new char [j * 2 ];
int k = 0 ;
for ( int i = 0 ; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf ];
str[k++] = hexDigits[byte0 & 0xf ];
}
return new String(str);
} catch (Exception e) {
return null ;
}
}
public static void main(String[] args) {
// MD5_Test aa = new MD5_Test();
System.out.print(MD5_test.MD5("a" ));
// System.out.print(MD5_test.MD5("%7B%7DAHRCU" ));
}
}
这两种方案都可解决并发问题。
java MD5 并发的更多相关文章
- Java高并发秒杀API之Service层
Java高并发秒杀API之Service层 第1章 秒杀业务接口设计与实现 1.1service层开发之前的说明 开始Service层的编码之前,我们首先需要进行Dao层编码之后的思考:在Dao层我们 ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- Java线程并发:知识点
Java线程并发:知识点 发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用. 逃逸:在对象尚未准备 ...
- 【实战Java高并发程序设计 7】让线程之间互相帮助--SynchronousQueue的实现
[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...
- 【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现
[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...
- 【实战Java高并发程序设计 5】让普通变量也享受原子操作
[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...
- 【实战Java高并发程序设计 4】数组也能无锁:AtomicIntegerArray
除了提供基本数据类型外,JDK还为我们准备了数组等复合结构.当前可用的原子数组有:AtomicIntegerArray.AtomicLongArray和AtomicReferenceArray,分别表 ...
- 【实战Java高并发程序设计 3】带有时间戳的对象引用:AtomicStampedReference
[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference AtomicReference无法解决上述问题的根 ...
- 【实战Java高并发程序设计 1】Java中的指针:Unsafe类
是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...
随机推荐
- linux中内核延时函数 (转)
第一类延时函数原型是:(忙等) void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsi ...
- 微软正式发布Windows 1.0 回顾历代Windows版本界面
在刚过去的上月底,Windows XP过完了12岁生日,在今天我们又欢快地迎来了Windows的生日.在1985年11月20日,微软正式发布Windows 1.0,它基于的是MS-DOS系统,实际上其 ...
- mark TODO:完善拦截规则;日志分析;web仪表盘展示;终极目标动态配置规则
- Spring整合Hibernate,Druid(Maven)
本文转载自:http://blog.csdn.net/lantazy/article/details/52495839 首先,说一下spring,spring有很好的整合能力,Web应用的各个层次都能 ...
- 服务器选型:x86 vs 小型机谁更胜一筹?
市场上关于X86 和小型机的争论从来就没有停止过,在以往的印象当中,x86服务器在中低端形成了统治之势,而小型机则在关键性应用领域(金融.证券.政府等)享有王者地位.但是随着X86服务器的不断发展,这 ...
- delphi Firemonkey ListView 使用参考
delphi Firemonkey ListView 使用参考 Tokyo版本 http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Customizin ...
- forbidden Derby database starting with weblogic instance
Now doing a new project which choose the newest weblogic 12.1.2.0.0 as web container.But found the ...
- Maven(三)理解Maven核心概念
转载自: http://www.cnblogs.com/holbrook/archive/2012/12/24/2830519.html 本文以类图的方式,介绍maven核心的12个概念以及相互之间的 ...
- Cloudera Manger CDH 安装文档
简介: Cloudera Manager 是 Cloudera 公司推出的 Hadoop 集群管理工具,通过该管理工具可以方便的部署.配置.监控集群. Cloudera 公司自己发布的 Hadoop ...
- maven的pom报plugins缺失的解决方法
maven的pom报plugins却是的解决方法. 引用 Failure to transfer org.apache.maven.plugins:maven-surefire-plugin:pom: ...