When performing a performance test, I found a problem with an MD5 tool class. under heavy pressure, I encountered a computing error. I analyzed the code and found the cause.
Here is the original code:
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 ();
}
}
}
Here is the modified Code:
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 ();
}
}
}
The main differences are as follows:
Synchronized (md ){
Md. reset ();
Return md. digest (data );
}
This article is from the "Hai Li Bu's column" blog