在做性能测试的时候,发现一个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);
- }