在做性能測試的時候,發現一個MD5的工具類有問題,在大壓力的情況下,會出現計算出錯的問題,分析瞭一下代碼,找到瞭原因所在。
這是原來的代碼:
public class MD5 {
// ———————————————————— Private data
private static SecureRandom random = null;
private static MessageDigest md = null;
// ———————————————————— Constructors
/** Creates a new instance of MD5 */
protected MD5() {
}
// ———————————————————- Public methods
/**
* Returns a new nonce to be used for MD5 authentication. The nonce bytes
* are guaranteed to be in the printable range from ascii 32 to 128.
*
* @return a new 16 bytes long nonce
*/
public static byte[] getNextNonce() {
byte[] nextNonce = new byte[16];
random.nextBytes(nextNonce);
int i;
for (int j=0; j<nextNonce.length; ++j) {
i = nextNonce[j] & 0x000000ff;
if ((i<32) || (i>128)) {
nextNonce[j] = (byte)(32 + (i % 64));
}
}
return nextNonce;
}
/**
* MD5ies the given content
*
* @param data the data to be digested
*
*/
public static byte[] digest(byte[] data) {
md.reset();
return md.digest(data);
}
// ——————————————————— Private methods
/**
* Creates and initialize the random generator. Called ad class loading
* time.
*/
private static void randomGeneratorInit()
throws java.security.NoSuchAlgorithmException {
random = SecureRandom.getInstance("SHA1PRNG");
}
// ————————————————————- Static code
static {
try {
randomGeneratorInit();
md = MessageDigest.getInstance("MD5");
} catch(Exception e) {
e.printStackTrace();
}
}
}
這是我修改後的代碼:
public class MD5 {
// ———————————————————— Private data
private static SecureRandom random = null;
private static MessageDigest md = null;
// ———————————————————— Constructors
/** Creates a new instance of MD5 */
protected MD5() {
}
// ———————————————————- Public methods
/**
* Returns a new nonce to be used for MD5 authentication. The nonce bytes
* are guaranteed to be in the printable range from ascii 32 to 128.
*
* @return a new 16 bytes long nonce
*/
public static byte[] getNextNonce() {
byte[] nextNonce = new byte[16];
random.nextBytes(nextNonce);
int i;
for (int j=0; j<nextNonce.length; ++j) {
i = nextNonce[j] & 0x000000ff;
if ((i<32) || (i>128)) {
nextNonce[j] = (byte)(32 + (i % 64));
}
}
return nextNonce;
}
/**
* MD5ies the given content
*
* @param data the data to be digested
*
*/
public static byte[] digest(byte[] data) {
synchronized (md) {
md.reset();
return md.digest(data);
}
}
// ——————————————————— Private methods
/**
* Creates and initialize the random generator. Called ad class loading
* time.
*/
private static void randomGeneratorInit()
throws java.security.NoSuchAlgorithmException {
random = SecureRandom.getInstance("SHA1PRNG");
}
// ————————————————————- Static code
static {
try {
randomGeneratorInit();
md = MessageDigest.getInstance("MD5");
} catch(Exception e) {
e.printStackTrace();
}
}
}
主要區別在這裡:
synchronized (md) {
md.reset();
return md.digest(data);
}
本文出自 “海力佈的專欄” 博客