mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
优化MD5性能
This commit is contained in:
parent
52135e9aeb
commit
049086aa79
@ -17,10 +17,11 @@
|
||||
* 【http 】 修复HttpDownloader.downloadFile 方法缺少static问题(issue#I6Z8VU@Gitee)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
# 5.8.18 (2023-04-16)
|
||||
# 5.8.18 (2023-05-04)
|
||||
|
||||
### 🐣新特性
|
||||
* 【extra 】 JschUtil新增一个重载方法以支持私钥以byte数组形式载入(pr#3057@Github)
|
||||
* 【crypto】 优化MD5性能(issue#I6ZIQH@Gitee)
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【core 】 修复CollUtil.reverseNew针对非可变列表异常(issue#3056@Github)
|
||||
|
@ -1057,6 +1057,20 @@ public class SecureUtil {
|
||||
return messageDigest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建{@link MessageDigest},使用JDK默认的Provider<br>
|
||||
*
|
||||
* @param algorithm 算法
|
||||
* @return {@link MessageDigest}
|
||||
*/
|
||||
public static MessageDigest createJdkMessageDigest(final String algorithm) {
|
||||
try {
|
||||
return MessageDigest.getInstance(algorithm);
|
||||
} catch (final NoSuchAlgorithmException e) {
|
||||
throw new CryptoException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建{@link Mac}
|
||||
*
|
||||
|
@ -77,6 +77,15 @@ public class Digester implements Serializable {
|
||||
public Digester(String algorithm, Provider provider) {
|
||||
init(algorithm, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param messageDigest {@link MessageDigest}
|
||||
*/
|
||||
public Digester(final MessageDigest messageDigest) {
|
||||
this.digest = messageDigest;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------- Constructor end
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package cn.hutool.crypto.digest;
|
||||
|
||||
import cn.hutool.crypto.GlobalBouncyCastleProvider;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* {@link Digester}创建简单工厂,用于生产{@link Digester}对象<br>
|
||||
* 参考Guava方式,工厂负责持有一个原始的{@link MessageDigest}对象,使用时优先通过clone方式创建对象,提高初始化性能。
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class DigesterFactory {
|
||||
|
||||
/**
|
||||
* 创建工厂
|
||||
*
|
||||
* @param algorithm 算法
|
||||
* @return DigesterFactory
|
||||
*/
|
||||
public static DigesterFactory ofJdk(final String algorithm) {
|
||||
return of(SecureUtil.createJdkMessageDigest(algorithm));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建工厂,使用{@link GlobalBouncyCastleProvider}找到的提供方。
|
||||
*
|
||||
* @param algorithm 算法
|
||||
* @return DigesterFactory
|
||||
*/
|
||||
public static DigesterFactory of(final String algorithm) {
|
||||
return of(SecureUtil.createMessageDigest(algorithm));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建工厂
|
||||
*
|
||||
* @param messageDigest {@link MessageDigest},可以通过{@link SecureUtil#createMessageDigest(String)} 创建
|
||||
* @return DigesterFactory
|
||||
*/
|
||||
public static DigesterFactory of(final MessageDigest messageDigest) {
|
||||
return new DigesterFactory(messageDigest);
|
||||
}
|
||||
|
||||
private final MessageDigest prototype;
|
||||
private final boolean cloneSupport;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param messageDigest {@link MessageDigest}模板
|
||||
*/
|
||||
private DigesterFactory(final MessageDigest messageDigest) {
|
||||
this.prototype = messageDigest;
|
||||
this.cloneSupport = checkCloneSupport(messageDigest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建{@link Digester}
|
||||
*
|
||||
* @return {@link Digester}
|
||||
*/
|
||||
public Digester createDigester() {
|
||||
return new Digester(createMessageDigester());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建{@link MessageDigest}
|
||||
*
|
||||
* @return {@link MessageDigest}
|
||||
*/
|
||||
public MessageDigest createMessageDigester() {
|
||||
if (cloneSupport) {
|
||||
try {
|
||||
return (MessageDigest) prototype.clone();
|
||||
} catch (final CloneNotSupportedException ignore) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return SecureUtil.createJdkMessageDigest(prototype.getAlgorithm());
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查{@link MessageDigest}对象是否支持clone方法
|
||||
*
|
||||
* @param messageDigest {@link MessageDigest}
|
||||
* @return 是否支持clone方法
|
||||
*/
|
||||
private static boolean checkCloneSupport(final MessageDigest messageDigest) {
|
||||
try {
|
||||
messageDigest.clone();
|
||||
return true;
|
||||
} catch (final CloneNotSupportedException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,10 @@ import java.nio.charset.Charset;
|
||||
public class MD5 extends Digester {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// issue#I6ZIQH
|
||||
// MD5算法不使用BC库,使用JDK默认以提高初始性能
|
||||
private static final DigesterFactory FACTORY = DigesterFactory.ofJdk(DigestAlgorithm.MD5.getValue());
|
||||
|
||||
/**
|
||||
* 创建MD5实例
|
||||
*
|
||||
@ -27,7 +31,7 @@ public class MD5 extends Digester {
|
||||
* 构造
|
||||
*/
|
||||
public MD5() {
|
||||
super(DigestAlgorithm.MD5);
|
||||
super(FACTORY.createMessageDigester());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.hutool.crypto.digest;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.thread.ConcurrencyTester;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -17,4 +19,15 @@ public class Md5Test {
|
||||
Assert.assertEquals(16, hex16.length());
|
||||
Assert.assertEquals("cb143acd6c929826", hex16);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void md5ThreadSafeTest() {
|
||||
final String text = "Hutool md5 test str";
|
||||
final ConcurrencyTester tester = new ConcurrencyTester(1000);
|
||||
tester.test(()->{
|
||||
final String digest = new MD5().digestHex(text);
|
||||
Assert.assertEquals("8060075dd8df47bac3247438e940a728", digest);
|
||||
});
|
||||
IoUtil.close(tester);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user