使用JAVA進行MD5加密后所遇到的一些問題


  前言:這幾天在研究apache shiro如何使用,這好用到了給密碼加密的地方,就碰巧研究了下java的MD5加密是如何實現的,下面記錄下我遇到的一些小問題。

 

  使用java進行MD5加密非常的簡單,代碼如下:

  public static void main(String[] args) throws Exception
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String password = "wodemima";
        byte[] bytes = md5.digest(password.getBytes());
    }

  但是,當我將bytes直接轉換成字符串並且存入數據庫的時候我發現了問題,怎么顯示的是個亂碼呢,顯示的是如下亂碼:

�'D���:�@�
��&

  我頓時感覺這真是加密了,肯定妥妥的破解不了,但是一般加密后顯示的是32位16進制字符串,為什么我這顯示亂碼了呢。原來是還有一個步驟,就是需要將byte數組轉換成16進行,代碼如下:

  public static void main(String[] args) throws Exception
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String password = "wodemima";
        byte[] bytes = md5.digest(password.getBytes());
        String result = "";
        for(byte b : bytes)
        {
            result = result + Integer.toHexString(b);
        }
        System.out.println(result);
    }
  //輸出顯示:fffffffb2744ffffffd1ffffffe419ffffff813affffffde40ffffffefaffffff97ffffffc5261f

  這下子算是像模像樣了,但是貌似不是32位,並且有好多fff,原來是返回的byte數組當中有負數,但是有負數為什么會造成這樣的結果呢,於是乎我就復習了下java當中的基本類型。

  基本類型表如下:
數據類型            大小                  范圍                                             默認值 

byte(字節)          8                 -128 - 127                                            0
shot(短整型)        16               -32768 - 32767                                         0
int(整型)           32            -2147483648 - 2147483647                                  0
long(長整型)        64    -9233372036854477808-9233372036854477807                          0        
float(浮點型)       32          1.4E-45 - 3.40292347E+38                                0.0f
double(雙精度)      64       4.9E-324 - 1.79769313486231570E+308                      0.0d
char(字符型)        16            ‘ \u0000 - u\ffff ’                                   ‘\u0000 ’
boolean(布爾型)     1                 true/false                                          false

 

   我原來上大學的時候一直在困惑為什么占8位最大值不是128,后來我發現原來還有個0呢。。不知道算不算是頓悟。。。。。

  於Integer.toHexString(b);方法傳入的值是int類型的,所以當我傳入byte的時候就會自動轉換成int類型,又由於byte類型只占8位並且int類型占32位,所以會進行補位,如果byte是整數的話沒什么影響,因為前面補的是0。

  但是如果是負數的話就會出現問題了,例如byte b = -112; byte的2進制表示為:1001 0000,java中是以補碼的形式進行表示的。(補碼我就不介紹了,可以百度查閱。)這樣前面補滿22位個1的時候就會出現很多f。

  於是我把代碼改成下面這個樣子:

  public static void main(String[] args) throws Exception
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String password = "wodemima";
        byte[] bytes = md5.digest(password.getBytes());
        String result = "";
        for(byte b : bytes)
        {
            result = result + Integer.toHexString(b & 0xff);
       //b &
0xff 是為了取低8位
     } 
     System.out.println(result);
  }
  //輸出顯示:fb2744d1e419813ade40efa97c5261f
 

 

   這次更像那么回事了,但是我查了一下31位。為什么會少一位,原來byte數組中有的值可能小於16,所以轉換成16進制的時候用1位就可以表示了。這個時候我們應該在前面加上個0。

  代碼如下:

  public static void main(String[] args) throws Exception
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String password = "wodemima";
        byte[] bytes = md5.digest(password.getBytes());
        String result = "";
        for(byte b : bytes)
        {
            String temp = Integer.toHexString(b & 0xff);
            if(temp.length() == 1)
            {
                temp = "0" + temp;
            }
            result = result + temp;
        }
        System.out.println(result);
    }
  //輸出顯示:fb2744d1e419813ade40ef0a97c5261f
 

 

   好了,這次正確了。這就是我記錄的一些問題,有些細節不注意還真不知道怎么回事。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM