2025-05-24

 

在做性能測試的時候,發現一個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);

        }

 

 

 

本文出自 “海力佈的專欄” 博客

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *