當前位置:首頁 » 密碼管理 » md5加密演算法java

md5加密演算法java

發布時間: 2023-11-01 14:06:44

java MD5加密,解釋解釋!

給你解釋一下for裡面這段代碼
byte byte0 = md[i];//取得md數組中第i個元素

str[k++] = hexDigits[byte0 >>> 4 & 0xf ];取得byte0的前四位,然後找到轉化成16進制字元,如果byte0為10001000(二進制)那麼前四位就是1000,十進制就是8,而 hexDigits[8]就=『8』
str[k++] = hexDigits[byte0 & 0xf ]; //同理取得byte0的後四位,轉化成16進制字元。

Ⅱ java中使用MD5加密演算法進行加密

在各種應用系統的開發中 經常需要存儲用戶信息 很多地方都要存儲用戶密碼 而將用戶密碼直接存儲亮衫唯在伺服器上顯然是不安全的 本文簡要介紹工作中常用的 MD 加密演算法 希望能拋磚引玉

(一)消息摘要簡介

一個消息摘要就是一個數據塊的數字指紋 即對一個任意敬培長度的一個數據塊進行計算 產生一個唯一指印(對於SHA 是產生一個 位元組的二進制數組) 消息摘要是一種與消息認證碼結合使用以確保消息完整性的技術 主要使用單向散列函數演算法 可用於檢驗消息的完整性 和通過散列密碼直接以文本形式保存等 目前廣泛使用的演算法有MD MD SHA

消息摘要有兩個基本屬性

兩個不同的報文難以生成相同的摘要難以對指定的摘要生成一個報文 而可以由該報文反推算出該指定的摘要代表 美國國家標准技術研究所的SHA 和麻省理工學院Ronald Rivest提出的MD

(二)對字元串進行加密

/***//**利用MD 進行加密*@paramstr待加密的字元串*@return加密後的字元串*塌仔@沒有這種產生消息摘要的演算法*@*/publicStringEncoderByMd (Stringstr) UnsupportedEncodingException {//確定計算方法MessageDigestmd =MessageDigest getInstance( MD );BASE Encoderbase en=newBASE Encoder();//加密後的字元串Stringnewstr=base en encode(md digest(str getBytes( utf )));returnnewstr;}

調用函數 String str=

System out println(EncoderByMd (str))

輸出 eB eJF ptWaXm bijSPyxw==

(三)驗證密碼是否正確

/***//**判斷用戶密碼是否正確*@paramnewpasswd用戶輸入的密碼*@paramoldpasswd資料庫中存儲的密碼--用戶密碼的摘要*@return*@*@*/publicbooleancheckpassword(Stringnewpasswd Stringoldpasswd) UnsupportedEncodingException {if(EncoderByMd (newpasswd) equals(oldpasswd))returntrue;elsereturnfalse;} lishixin/Article/program/Java/hx/201311/26374

Ⅲ 如何在java中實現md5加密和解密

package endecrypt;
02.
03.import java.io.UnsupportedEncodingException;
04.import java.security.MessageDigest;
05.import java.security.NoSuchAlgorithmException;
06.
07./**
08. * 採用MD5加密解密
09. * @author tfq
10. * @datetime 2011-10-13
11. */
12.public class MD5Util {
13.
14. /***
15. * MD5加碼 生成32位md5碼
16. */
17. public static String string2MD5(String inStr){
18. MessageDigest md5 = null;
19. try{
20. md5 = MessageDigest.getInstance("MD5");
21. }catch (Exception e){
22. System.out.println(e.toString());
23. e.printStackTrace();
24. return "";
25. }
26. char[] charArray = inStr.toCharArray();
27. byte[] byteArray = new byte[charArray.length];
28.
29. for (int i = 0; i < charArray.length; i++)
30. byteArray[i] = (byte) charArray[i];
31. byte[] md5Bytes = md5.digest(byteArray);
32. StringBuffer hexValue = new StringBuffer();
33. for (int i = 0; i < md5Bytes.length; i++){
34. int val = ((int) md5Bytes[i]) & 0xff;
35. if (val < 16)
36. hexValue.append("0");
37. hexValue.append(Integer.toHexString(val));
38. }
39. return hexValue.toString();
40.
41. }
42.
43. /**
44. * 加密解密演算法 執行一次加密,兩次解密
45. */
46. public static String convertMD5(String inStr){
47.
48. char[] a = inStr.toCharArray();
49. for (int i = 0; i < a.length; i++){
50. a[i] = (char) (a[i] ^ 't');
51. }
52. String s = new String(a);
53. return s;
54.
55. }

Ⅳ 可變MD5加密(Java實現)

可變在這里含義很簡單 就是最終的加密結果是可變的 而非必需按標准MD 加密實現 Java類庫security中的MessageDigest類就提供了MD 加密的支持 實現起來非常方便 為了實現更多效果 我們可以如下設計MD 工具類

Java代碼

package ** ** util;

import java security MessageDigest;

/**

* 標准MD 加密方法 使用java類庫的security包的MessageDigest類處理

* @author Sarin

*/

public class MD {

/**

* 獲得MD 加密密碼的方法

*/

public static String getMD ofStr(String origString) {

String origMD = null;

try {

MessageDigest md = MessageDigest getInstance( MD );

byte[] result = md digest(origString getBytes());

origMD = byteArray HexStr(result);

} catch (Exception e) {

e printStackTrace();

}

return origMD ;

}

/**

* 處理位元組數組得到MD 密碼的方法

*/

private static String byteArray HexStr(byte[] bs) {

StringBuffer *** = new StringBuffer();

for (byte b : bs) {

*** append(byte HexStr(b));

}

return *** toString();

}

/**

* 位元組標准移位轉十六進制方法

*/

private static String byte HexStr(byte b) {

String hexStr = null;

int n = b;

if (n < ) {

//若需要自定義加密 請修改這個移位演算法即可

n = b & x F + ;

}

hexStr = Integer toHexString(n / ) + Integer toHexString(n % );

return hexStr toUpperCase();

}

/**

* 提供一個MD 多次加密方法

*/

public static String getMD ofStr(String origString int times) {

String md = getMD ofStr(origString);

for (int i = ; i < times ; i++) {

md = getMD ofStr(md );

}

return getMD ofStr(md );

}

/**

* 密碼驗證方法

*/

public static boolean verifyPassword(String inputStr String MD Code) {

return getMD ofStr(inputStr) equals(MD Code);

}

/**

* 重載一個多次加密時的密碼驗證方法

*/

public static boolean verifyPassword(String inputStr String MD Code int times) {

return getMD ofStr(inputStr times) equals(MD Code);

}

/**

* 提供一個測試的主函數

*/

public static void main(String[] args) {

System out println( : + getMD ofStr( ));

System out println( : + getMD ofStr( ));

System out println( sarin: + getMD ofStr( sarin ));

System out println( : + getMD ofStr( ));

}

}

可以看出實現的過程非常簡單 因為由java類庫提供了處理支持 但是要清楚的是這種方式產生的密碼不是標準的MD 碼 它需要進行移位處理才能得到標准MD 碼 這個程序的關鍵之處也在這了 怎麼可變?調整移位演算法不就可變了么!不進行移位 也能夠得到 位的密碼 這就不是標准加密了 只要加密和驗證過程使用相同的演算法就可以了

MD 加密還是很安全的 像CMD 那些窮舉破解的只是針對標准MD 加密的結果進行的 如果自定義移位演算法後 它還有效么?可以說是無解的了 所以MD 非常安全可靠

為了更可變 還提供了多次加密的方法 可以在MD 基礎之上繼續MD 就是對 位的第一次加密結果再MD 恩 這樣去破解?沒有任何意義

這樣在MIS系統中使用 安全可靠 歡迎交流 希望對使用者有用

我們最後看看由MD 加密演算法實現的類 那是非常龐大的

Java代碼

import java lang reflect *;

/**

* **********************************************

* md 類實現了RSA Data Security Inc 在提交給IETF

* 的RFC 中的MD message digest 演算法

* ***********************************************

*/

public class MD {

/* 下面這些S S 實際上是一個 * 的矩陣 在原始的C實現中是用#define 實現的

這里把它們實現成為static final是表示了只讀 切能在同一個進程空間內的多個

Instance間共享*/

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final int S = ;

static final byte[] PADDING = {

};

/* 下面的三個成員是MD 計算過程中用到的 個核心數據 在原始的C實現中

被定義到MD _CTX結構中

*/

private long[] state = new long[ ]; // state (ABCD)

private long[] count = new long[ ]; // number of bits molo ^ (l *** first)

private byte[] buffer = new byte[ ]; // input buffer

/* digestHexStr是MD 的唯一一個公共成員 是最新一次計算結果的

進制ASCII表示

*/

public String digestHexStr;

/* digest 是最新一次計算結果的 進制內部表示 表示 bit的MD 值

*/

private byte[] digest = new byte[ ];

/*

getMD ofStr是類MD 最主要的公共方法 入口參數是你想要進行MD 變換的字元串

返回的是變換完的結果 這個結果是從公共成員digestHexStr取得的.

*/

public String getMD ofStr(String inbuf) {

md Init();

md Update(inbuf getBytes() inbuf length());

md Final();

digestHexStr = ;

for (int i = ; i < ; i++) {

digestHexStr += byteHEX(digest[i]);

}

return digestHexStr;

}

// 這是MD 這個類的標准構造函數 JavaBean要求有一個public的並且沒有參數的構造函數

public MD () {

md Init();

return;

}

/* md Init是一個初始化函數 初始化核心變數 裝入標準的幻數 */

private void md Init() {

count[ ] = L;

count[ ] = L;

///* Load magic initialization constants

state[ ] = x L;

state[ ] = xefcdab L;

state[ ] = x badcfeL;

state[ ] = x L;

return;

}

/* F G H I 是 個基本的MD 函數 在原始的MD 的C實現中 由於它們是

簡單的位運算 可能出於效率的考慮把它們實現成了宏 在java中 我們把它們

實現成了private方法 名字保持了原來C中的 */

private long F(long x long y long z) {

return (x & y) | ((~x) & z);

}

private long G(long x long y long z) {

return (x & z) | (y & (~z));

}

private long H(long x long y long z) {

return x ^ y ^ z;

}

private long I(long x long y long z) {

return y ^ (x | (~z));

}

/*

FF GG HH和II將調用F G H I進行近一步變換

FF GG HH and II transformations for rounds and

Rotation is separate from addition to prevent reputation

*/

private long FF(long a long b long c long d long x long s long ac) {

a += F(b c d) + x + ac;

a = ((int) a << s) | ((int) a >>> ( s));

a += b;

return a;

}

private long GG(long a long b long c long d long x long s long ac) {

a += G(b c d) + x + ac;

a = ((int) a << s) | ((int) a >>> ( s));

a += b;

return a;

}

private long HH(long a long b long c long d long x long s long ac) {

a += H(b c d) + x + ac;

a = ((int) a << s) | ((int) a >>> ( s));

a += b;

return a;

}

private long II(long a long b long c long d long x long s long ac) {

a += I(b c d) + x + ac;

a = ((int) a << s) | ((int) a >>> ( s));

a += b;

return a;

}

/*

md Update是MD 的主計算過程 inbuf是要變換的位元組串 inputlen是長度 這個

函數由getMD ofStr調用 調用之前需要調用md init 因此把它設計成private的

*/

private void md Update(byte[] inbuf int inputLen) {

int i index partLen;

byte[] block = new byte[ ];

index = (int) (count[ ] >>> ) & x F;

// /* Update number of bits */

if ((count[ ] += (inputLen << )) < (inputLen << ))

count[ ]++;

count[ ] += (inputLen >>> );

partLen = index;

// Transform as many times as possible

if (inputLen >= partLen) {

md Memcpy(buffer inbuf index partLen);

md Transform(buffer);

for (i = partLen; i + < inputLen; i += ) {

md Memcpy(block inbuf i );

md Transform(block);

}

index = ;

} else

i = ;

///* Buffer remaining input */

md Memcpy(buffer inbuf index i inputLen i);

}

/*

md Final整理和填寫輸出結果

*/

private void md Final() {

byte[] bits = new byte[ ];

int index padLen;

///* Save number of bits */

Encode(bits count );

///* Pad out to mod

index = (int) (count[ ] >>> ) & x f;

padLen = (index < ) ? ( index) : ( index);

md Update(PADDING padLen);

///* Append length (before padding) */

md Update(bits );

///* Store state in digest */

Encode(digest state );

}

/* md Memcpy是一個內部使用的byte數組的塊拷貝函數 從input的inpos開始把len長度的

位元組拷貝到output的outpos位置開始

*/

private void md Memcpy(byte[] output byte[] input int outpos int inpos int len) {

int i;

for (i = ; i < len; i++)

output[outpos + i] = input[inpos + i];

}

/*

md Transform是MD 核心變換程序 有md Update調用 block是分塊的原始位元組

*/

private void md Transform(byte block[]) {

long a = state[ ] b = state[ ] c = state[ ] d = state[ ];

long[] x = new long[ ];

Decode(x block );

/* Round */

a = FF(a b c d x[ ] S xd aa L); /* */

d = FF(d a b c x[ ] S xe c b L); /* */

c = FF(c d a b x[ ] S x dbL); /* */

b = FF(b c d a x[ ] S xc bdceeeL); /* */

a = FF(a b c d x[ ] S xf c fafL); /* */

d = FF(d a b c x[ ] S x c aL); /* */

c = FF(c d a b x[ ] S xa L); /* */

b = FF(b c d a x[ ] S xfd L); /* */

a = FF(a b c d x[ ] S x d L); /* */

d = FF(d a b c x[ ] S x b f afL); /* */

c = FF(c d a b x[ ] S xffff bb L); /* */

b = FF(b c d a x[ ] S x cd beL); /* */

a = FF(a b c d x[ ] S x b L); /* */

d = FF(d a b c x[ ] S xfd L); /* */

c = FF(c d a b x[ ] S xa eL); /* */

b = FF(b c d a x[ ] S x b L); /* */

/* Round */

a = GG(a b c d x[ ] S xf e L); /* */

d = GG(d a b c x[ ] S xc b L); /* */

c = GG(c d a b x[ ] S x e a L); /* */

b = GG(b c d a x[ ] S xe b c aaL); /* */

a = GG(a b c d x[ ] S xd f dL); /* */

d = GG(d a b c x[ ] S x L); /* */

c = GG(c d a b x[ ] S xd a e L); /* */

b = GG(b c d a x[ ] S xe d fbc L); /* */

a = GG(a b c d x[ ] S x e cde L); /* */

d = GG(d a b c x[ ] S xc d L); /* */

c = GG(c d a b x[ ] S xf d d L); /* */

b = GG(b c d a x[ ] S x a edL); /* */

a = GG(a b c d x[ ] S xa e e L); /* */

d = GG(d a b c x[ ] S xfcefa f L); /* */

c = GG(c d a b x[ ] S x f d L); /* */

b = GG(b c d a x[ ] S x d a c aL); /* */

/* Round */

a = HH(a b c d x[ ] S xfffa L); /* */

d = HH(d a b c x[ ] S x f L); /* */

c = HH(c d a b x[ ] S x d d L); /* */

b = HH(b c d a x[ ] S xfde cL); /* */

a = HH(a b c d x[ ] S xa beea L); /* */

d = HH(d a b c x[ ] S x bdecfa L); /* */

c = HH(c d a b x[ ] S xf bb b L); /* */

b = HH(b c d a x[ ] S xbebfbc L); /* */

a = HH(a b c d x[ ] S x b ec L); /* */

d = HH(d a b c x[ ] S xeaa faL); /* */

c = HH(c d a b x[ ] S xd ef L); /* */

b = HH(b c d a x[ ] S x d L); /* */

a = HH(a b c d x[ ] S xd d d L); /* */

d = HH(d a b c x[ ] S xe db e L); /* */

c = HH(c d a b x[ ] S x fa cf L); /* */

b = HH(b c d a x[ ] S xc ac L); /* */

/* Round */

a = II(a b c d x[ ] S xf L); /* */

d = II(d a b c x[ ] S x aff L); /* */

c = II(c d a b x[ ] S xab a L); /* */

b = II(b c d a x[ ] S xfc a L); /* */

a = II(a b c d x[ ] S x b c L); /* */

d = II(d a b c x[ ] S x f ccc L); /* */

c = II(c d a b x[ ] S xffeff dL); /* */

b = II(b c d a x[ ] S x dd L); /* */

a = II(a b c d x[ ] S x fa e fL); /* */

d = II(d a b c x[ ] S xfe ce e L); /* */

c = II(c d a b x[ ] S xa L); /* */

b = II(b c d a x[ ] S x e a L); /* */

a = II(a b c d x[ ] S xf e L); /* */

d = II(d a b c x[ ] S xbd af L); /* */

c = II(c d a b x[ ] S x ad d bbL); /* */

b = II(b c d a x[ ] S xeb d L); /* */

state[ ] += a;

state[ ] += b;

state[ ] += c;

state[ ] += d;

}

/*Encode把long數組按順序拆成byte數組 因為java的long類型是 bit的

只拆低 bit 以適應原始C實現的用途

*/

private void Encode(byte[] output long[] input int len) {

int i j;

for (i = j = ; j < len; i++ j += ) {

output[j] = (byte) (input[i] & xffL);

output[j + ] = (byte) ((input[i] >>> ) & xffL);

output[j + ] = (byte) ((input[i] >>> ) & xffL);

output[j + ] = (byte) ((input[i] >>> ) & xffL);

}

}

/*Decode把byte數組按順序合成成long數組 因為java的long類型是 bit的

只合成低 bit 高 bit清零 以適應原始C實現的用途

*/

private void Decode(long[] output byte[] input int len) {

int i j;

for (i = j = ; j < len; i++ j += )

output[i] = b iu(input[j]) | (b iu(input[j + ]) << ) | (b iu(input[j + ]) << )

| (b iu(input[j + ]) << );

return;

}

/*

b iu是我寫的一個把byte按照不考慮正負號的原則的"升位"程序 因為java沒有unsigned運算

*/

public static long b iu(byte b) {

return b < ? b & x F + : b;

}

/*byteHEX() 用來把一個byte類型的數轉換成十六進制的ASCII表示

因為java中的byte的toString無法實現這一點 我們又沒有C語言中的

sprintf(outbuf % X ib)

*/

public static String byteHEX(byte ib) {

char[] Digit = { A B C D E F };

char[] ob = new char[ ];

ob[ ] = Digit[(ib >>> ) & X F];

ob[ ] = Digit[ib & X F];

String s = new String(ob);

return s;

}

public static void main(String args[]) {

MD m = new MD ();

if (Array getLength(args) == ) { //如果沒有參數 執行標準的Test Suite

System out println( MD Test suite: );

System out println( MD ( ): + m getMD ofStr( ));

System out println( MD ( a ): + m getMD ofStr( a ));

System out println( MD ( abc ): + m getMD ofStr( abc ));

System out println( MD ( ): + m getMD ofStr( ));

System out println( MD ( ): + m getMD ofStr( ));

System out println( MD ( message digest ): + m getMD ofStr( message digest ));

System out println( MD ( abcdefghijklmnopqrstuvwxyz ): + m getMD ofStr( abcdefghijklmnopqrstuvwxyz ));

System out println( MD ( ):

+ m getMD ofStr( ));

} else

System out println( MD ( + args[ ] + )= + m getMD ofStr(args[ ]));

}

lishixin/Article/program/Java/hx/201311/26604

Ⅳ java如何算md5碼

可以利用JDK自帶的MD5來加密。

publicclassMD5Util{
publicfinalstaticStringMD5(Strings){
charhexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
try{
byte[]btInput=s.getBytes();
//獲得MD5摘要演算法的MessageDigest對象
MessageDigestmdInst=MessageDigest.getInstance("MD5");
//使用指定的位元組更新摘要
mdInst.update(btInput);
//獲得密文
byte[]md=mdInst.digest();
//把密文轉換成十六進制的字元串形式
intj=md.length;
charstr[]=newchar[j*2];
intk=0;
for(inti=0;i<j;i++){
bytebyte0=md[i];
str[k++]=hexDigits[byte0>>>4&0xf];
str[k++]=hexDigits[byte0&0xf];
}
returnnewString(str);
}catch(Exceptione){
e.printStackTrace();
returnnull;
}
}
publicstaticvoidmain(String[]args){
System.out.println(MD5Util.MD5("20121221"));
System.out.println(MD5Util.MD5("加密"));
}
}

Ⅵ java中md5加密

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class md5 {
public String str;

public void md5s(String plainText) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();

int i;

StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
str = buf.toString();
System.out.println("result: " + buf.toString());// 32位的加密
System.out.println("result: " + buf.toString().substring(8, 24));// 16位的加密
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}
}

public static void main(String agrs[]) {
md5 md51 = new md5();
md51.md5s("4");//加密4
}

}

Ⅶ java的MD5withRSA演算法可以看到解密的內容么

您好,
<一>. MD5加密演算法:
? ? ? ?消息摘要演算法第五版(Message Digest Algorithm),是一種單向加密演算法,只能加密、無法解密。然而MD5加密演算法已經被中國山東大學王小雲教授成功破譯,但是在安全性要求不高的場景下,MD5加密演算法仍然具有應用價值。
?1. 創建md5對象:?
<pre name="code" class="java">MessageDigest md5 = MessageDigest.getInstance("md5");
?2. ?進行加密操作:?
byte[] cipherData = md5.digest(plainText.getBytes());

?3. ?將其中的每個位元組轉成十六進制字元串:byte類型的數據最高位是符號位,通過和0xff進行與操作,轉換為int類型的正整數。?
String toHexStr = Integer.toHexString(cipher & 0xff);

?4. 如果該正數小於16(長度為1個字元),前面拼接0佔位:確保最後生成的是32位字元串。?
builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);

?5.?加密轉換之後的字元串為:?
?6. 完整的MD5演算法應用如下所示:?
/**
* 功能簡述: 測試MD5單向加密.
* @throws Exception
*/
@Test
public void test01() throws Exception {
String plainText = "Hello , world !";
MessageDigest md5 = MessageDigest.getInstance("md5");
byte[] cipherData = md5.digest(plainText.getBytes());
StringBuilder builder = new StringBuilder();
for(byte cipher : cipherData) {
String toHexStr = Integer.toHexString(cipher & 0xff);
builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);
}
System.out.println(builder.toString());
//
}

??
<二>. 使用BASE64進行加密/解密:
? ? ? ? 使用BASE64演算法通常用作對二進制數據進行加密,加密之後的數據不易被肉眼識別。嚴格來說,經過BASE64加密的數據其實沒有安全性可言,因為它的加密解密演算法都是公開的,典型的防菜鳥不防程序猿的呀。?經過標準的BASE64演算法加密後的數據,?通常包含/、+、=等特殊符號,不適合作為url參數傳遞,幸運的是Apache的Commons Codec模塊提供了對BASE64的進一步封裝。? (參見最後一部分的說明)
?1.?使用BASE64加密:?
BASE64Encoder encoder = new BASE64Encoder();
String cipherText = encoder.encode(plainText.getBytes());

? 2.?使用BASE64解密:?
BASE64Decoder decoder = new BASE64Decoder();
plainText = new String(decoder.decodeBuffer(cipherText));

? 3. 完整代碼示例:?
/**
* 功能簡述: 使用BASE64進行雙向加密/解密.
* @throws Exception
*/
@Test
public void test02() throws Exception {
BASE64Encoder encoder = new BASE64Encoder();
BASE64Decoder decoder = new BASE64Decoder();
String plainText = "Hello , world !";
String cipherText = encoder.encode(plainText.getBytes());
System.out.println("cipherText : " + cipherText);
//cipherText : SGVsbG8gLCB3b3JsZCAh
System.out.println("plainText : " +
new String(decoder.decodeBuffer(cipherText)));
//plainText : Hello , world !
}

??
<三>. 使用DES對稱加密/解密:
? ? ? ? ?數據加密標准演算法(Data Encryption Standard),和BASE64最明顯的區別就是有一個工作密鑰,該密鑰既用於加密、也用於解密,並且要求密鑰是一個長度至少大於8位的字元串。使用DES加密、解密的核心是確保工作密鑰的安全性。
?1.?根據key生成密鑰:?
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");
SecretKey secretKey = keyFactory.generateSecret(keySpec);

? 2.?加密操作:?
Cipher cipher = Cipher.getInstance("des");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());
byte[] cipherData = cipher.doFinal(plainText.getBytes());

? 3.?為了便於觀察生成的加密數據,使用BASE64再次加密:?
String cipherText = new BASE64Encoder().encode(cipherData);

? ? ?生成密文如下:PtRYi3sp7TOR69UrKEIicA==?
? 4.?解密操作:?
cipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());
byte[] plainData = cipher.doFinal(cipherData);
String plainText = new String(plainData);

? 5. 完整的代碼demo:?
/**
* 功能簡述: 使用DES對稱加密/解密.
* @throws Exception
*/
@Test
public void test03() throws Exception {
String plainText = "Hello , world !";
String key = "12345678"; //要求key至少長度為8個字元

SecureRandom random = new SecureRandom();
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");
SecretKey secretKey = keyFactory.generateSecret(keySpec);

Cipher cipher = Cipher.getInstance("des");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);
byte[] cipherData = cipher.doFinal(plainText.getBytes());
System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));
//PtRYi3sp7TOR69UrKEIicA==

cipher.init(Cipher.DECRYPT_MODE, secretKey, random);
byte[] plainData = cipher.doFinal(cipherData);
System.out.println("plainText : " + new String(plainData));
//Hello , world !
}

??
<四>. 使用RSA非對稱加密/解密:
? ? ? ? RSA演算法是非對稱加密演算法的典型代表,既能加密、又能解密。和對稱加密演算法比如DES的明顯區別在於用於加密、解密的密鑰是不同的。使用RSA演算法,只要密鑰足夠長(一般要求1024bit),加密的信息是不能被破解的。用戶通過https協議訪問伺服器時,就是使用非對稱加密演算法進行數據的加密、解密操作的。
? ? ? ?伺服器發送數據給客戶端時使用私鑰(private key)進行加密,並且使用加密之後的數據和私鑰生成數字簽名(digital signature)並發送給客戶端。客戶端接收到伺服器發送的數據會使用公鑰(public key)對數據來進行解密,並且根據加密數據和公鑰驗證數字簽名的有效性,防止加密數據在傳輸過程中被第三方進行了修改。
? ? ? ?客戶端發送數據給伺服器時使用公鑰進行加密,伺服器接收到加密數據之後使用私鑰進行解密。
?1.?創建密鑰對KeyPair:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");
keyPairGenerator.initialize(1024); //密鑰長度推薦為1024位.
KeyPair keyPair = keyPairGenerator.generateKeyPair();

? 2.?獲取公鑰/私鑰:
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

? 3.?伺服器數據使用私鑰加密:
Cipher cipher = Cipher.getInstance("rsa");
cipher.init(Cipher.ENCRYPT_MODE, privateKey, new SecureRandom());
byte[] cipherData = cipher.doFinal(plainText.getBytes());

? 4.?用戶使用公鑰解密:
cipher.init(Cipher.DECRYPT_MODE, publicKey, new SecureRandom());
byte[] plainData = cipher.doFinal(cipherData);

? 5.?伺服器根據私鑰和加密數據生成數字簽名:
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(cipherData);
byte[] signData = signature.sign();

? 6.?用戶根據公鑰、加密數據驗證數據是否被修改過:
signature.initVerify(publicKey);
signature.update(cipherData);
boolean status = signature.verify(signData);

? 7. RSA演算法代碼demo:<img src="http://www.cxyclub.cn/Upload/Images/2014081321/99A5FC9C0C628374.gif" alt="尷尬" title="尷尬" border="0">
/**
* 功能簡述: 使用RSA非對稱加密/解密.
* @throws Exception
*/
@Test
public void test04() throws Exception {
String plainText = "Hello , world !";

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();

PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

Cipher cipher = Cipher.getInstance("rsa");
SecureRandom random = new SecureRandom();

cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
byte[] cipherData = cipher.doFinal(plainText.getBytes());
System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));
//gDsJxZM98U2GzHUtUTyZ/Ir/
///ONFOD0fnJoGtIk+T/+3yybVL8M+RI+HzbE/jdYa/+
//yQ+vHwHqXhuzZ/N8iNg=

cipher.init(Cipher.DECRYPT_MODE, publicKey, random);
byte[] plainData = cipher.doFinal(cipherData);
System.out.println("plainText : " + new String(plainData));
//Hello , world !

Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(cipherData);
byte[] signData = signature.sign();
System.out.println("signature : " + new BASE64Encoder().encode(signData));
//+
//co64p6Sq3kVt84wnRsQw5mucZnY+/+vKKXZ3pbJMNT/4
///t9ewo+KYCWKOgvu5QQ=

signature.initVerify(publicKey);
signature.update(cipherData);
boolean status = signature.verify(signData);
System.out.println("status : " + status);
//true
}

Ⅷ java的md5的加密演算法代碼

import java.lang.reflect.*;

/*******************************************************************************
* keyBean 類實現了RSA Data Security, Inc.在提交給IETF 的RFC1321中的keyBean message-digest
* 演算法。
******************************************************************************/
public class keyBean {
/*
* 下面這些S11-S44實際上是一個4*4的矩陣,在原始的C實現中是用#define 實現的, 這里把它們實現成為static
* final是表示了只讀,切能在同一個進程空間內的多個 Instance間共享
*/
static final int S11 = 7;

static final int S12 = 12;

static final int S13 = 17;

static final int S14 = 22;

static final int S21 = 5;

static final int S22 = 9;

static final int S23 = 14;

static final int S24 = 20;

static final int S31 = 4;

static final int S32 = 11;

static final int S33 = 16;

static final int S34 = 23;

static final int S41 = 6;

static final int S42 = 10;

static final int S43 = 15;

static final int S44 = 21;

static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0 };

/*
* 下面的三個成員是keyBean計算過程中用到的3個核心數據,在原始的C實現中 被定義到keyBean_CTX結構中
*/
private long[] state = new long[4]; // state (ABCD)

private long[] count = new long[2]; // number of bits, molo 2^64 (lsb

// first)

private byte[] buffer = new byte[64]; // input buffer

/*
* digestHexStr是keyBean的唯一一個公共成員,是最新一次計算結果的 16進制ASCII表示.
*/

public String digestHexStr;

/*
* digest,是最新一次計算結果的2進制內部表示,表示128bit的keyBean值.
*/
private byte[] digest = new byte[16];

/*
* getkeyBeanofStr是類keyBean最主要的公共方法,入口參數是你想要進行keyBean變換的字元串
* 返回的是變換完的結果,這個結果是從公共成員digestHexStr取得的.
*/
public String getkeyBeanofStr(String inbuf) {
keyBeanInit();
keyBeanUpdate(inbuf.getBytes(), inbuf.length());
keyBeanFinal();
digestHexStr = "";
for (int i = 0; i < 16; i++) {
digestHexStr += byteHEX(digest[i]);
}
return digestHexStr;
}

// 這是keyBean這個類的標准構造函數,JavaBean要求有一個public的並且沒有參數的構造函數
public keyBean() {
keyBeanInit();
return;
}

/* keyBeanInit是一個初始化函數,初始化核心變數,裝入標準的幻數 */
private void keyBeanInit() {
count[0] = 0L;
count[1] = 0L;
// /* Load magic initialization constants.
state[0] = 0x67452301L;
state[1] = 0xefcdab89L;
state[2] = 0x98badcfeL;
state[3] = 0x10325476L;
return;
}

/*
* F, G, H ,I 是4個基本的keyBean函數,在原始的keyBean的C實現中,由於它們是
* 簡單的位運算,可能出於效率的考慮把它們實現成了宏,在java中,我們把它們 實現成了private方法,名字保持了原來C中的。
*/
private long F(long x, long y, long z) {
return (x & y) | ((~x) & z);
}

private long G(long x, long y, long z) {
return (x & z) | (y & (~z));
}

private long H(long x, long y, long z) {
return x ^ y ^ z;
}

private long I(long x, long y, long z) {
return y ^ (x | (~z));
}

/*
* FF,GG,HH和II將調用F,G,H,I進行近一步變換 FF, GG, HH, and II transformations for
* rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent
* recomputation.
*/
private long FF(long a, long b, long c, long d, long x, long s, long ac) {
a += F(b, c, d) + x + ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a += b;
return a;
}

private long GG(long a, long b, long c, long d, long x, long s, long ac) {
a += G(b, c, d) + x + ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a += b;
return a;
}

private long HH(long a, long b, long c, long d, long x, long s, long ac) {
a += H(b, c, d) + x + ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a += b;
return a;
}

private long II(long a, long b, long c, long d, long x, long s, long ac) {
a += I(b, c, d) + x + ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a += b;
return a;
}

/*
* keyBeanUpdate是keyBean的主計算過程,inbuf是要變換的位元組串,inputlen是長度,這個
* 函數由getkeyBeanofStr調用,調用之前需要調用keyBeaninit,因此把它設計成private的
*/
private void keyBeanUpdate(byte[] inbuf, int inputLen) {
int i, index, partLen;
byte[] block = new byte[64];
index = (int) (count[0] >>> 3) & 0x3F;
// /* Update number of bits */
if ((count[0] += (inputLen << 3)) < (inputLen << 3))
count[1]++;
count[1] += (inputLen >>> 29);
partLen = 64 - index;
// Transform as many times as possible.
if (inputLen >= partLen) {
keyBeanMemcpy(buffer, inbuf, index, 0, partLen);
keyBeanTransform(buffer);
for (i = partLen; i + 63 < inputLen; i += 64) {
keyBeanMemcpy(block, inbuf, 0, i, 64);
keyBeanTransform(block);
}
index = 0;
} else
i = 0;
// /* Buffer remaining input */
keyBeanMemcpy(buffer, inbuf, index, i, inputLen - i);
}

/*
* keyBeanFinal整理和填寫輸出結果
*/
private void keyBeanFinal() {
byte[] bits = new byte[8];
int index, padLen;
// /* Save number of bits */
Encode(bits, count, 8);
// /* Pad out to 56 mod 64.
index = (int) (count[0] >>> 3) & 0x3f;
padLen = (index < 56) ? (56 - index) : (120 - index);
keyBeanUpdate(PADDING, padLen);
// /* Append length (before padding) */
keyBeanUpdate(bits, 8);
// /* Store state in digest */
Encode(digest, state, 16);
}

/*
* keyBeanMemcpy是一個內部使用的byte數組的塊拷貝函數,從input的inpos開始把len長度的
* 位元組拷貝到output的outpos位置開始
*/
private void keyBeanMemcpy(byte[] output, byte[] input, int outpos,
int inpos, int len) {
int i;
for (i = 0; i < len; i++)
output[outpos + i] = input[inpos + i];
}

/*
* keyBeanTransform是keyBean核心變換程序,有keyBeanUpdate調用,block是分塊的原始位元組
*/
private void keyBeanTransform(byte block[]) {
long a = state[0], b = state[1], c = state[2], d = state[3];
long[] x = new long[16];
Decode(x, block, 64);
/* Round 1 */
a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */
/* Round 2 */
a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */
/* Round 3 */
a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */
/* Round 4 */
a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}

/*
* Encode把long數組按順序拆成byte數組,因為java的long類型是64bit的, 只拆低32bit,以適應原始C實現的用途
*/
private void Encode(byte[] output, long[] input, int len) {
int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (byte) (input[i] & 0xffL);
output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL);
output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL);
output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL);
}
}

/*
* Decode把byte數組按順序合成成long數組,因為java的long類型是64bit的,
* 只合成低32bit,高32bit清零,以適應原始C實現的用途
*/
private void Decode(long[] output, byte[] input, int len) {
int i, j;

for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8)
| (b2iu(input[j + 2]) << 16) | (b2iu(input[j + 3]) << 24);
return;
}

/*
* b2iu是我寫的一個把byte按照不考慮正負號的原則的」升位」程序,因為java沒有unsigned運算
*/
public static long b2iu(byte b) {
return b < 0 ? b & 0x7F + 128 : b;
}

/*
* byteHEX(),用來把一個byte類型的數轉換成十六進制的ASCII表示,
* 因為java中的byte的toString無法實現這一點,我們又沒有C語言中的 sprintf(outbuf,"%02X",ib)
*/
public static String byteHEX(byte ib) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'B', 'C', 'D', 'E', 'F' };
char[] ob = new char[2];
ob[0] = Digit[(ib >>> 4) & 0X0F];
ob[1] = Digit[ib & 0X0F];
String s = new String(ob);
return s;
}

public static void main(String args[]) {

keyBean m = new keyBean();
if (Array.getLength(args) == 0) { // 如果沒有參數,執行標準的Test Suite
System.out.println("keyBean Test suite:");
System.out.println("keyBean(\"):" + m.getkeyBeanofStr(""));
System.out.println("keyBean(\"a\"):" + m.getkeyBeanofStr("a"));
System.out.println("keyBean(\"abc\"):" + m.getkeyBeanofStr("abc"));
System.out.println("keyBean(\"message digest\"):"
+ m.getkeyBeanofStr("message digest"));
System.out.println("keyBean(\"abcdefghijklmnopqrstuvwxyz\"):"
+ m.getkeyBeanofStr("abcdefghijklmnopqrstuvwxyz"));
System.out
.println("keyBean(\"\"):"
+ m
.getkeyBeanofStr(""));
} else
System.out.println("keyBean(" + args[0] + ")="
+ m.getkeyBeanofStr(args[0]));

}
}

Ⅸ JAVA版MD5加密演算法

package sf_md ;

import java io *;

import java security *;

//import java util *;

//import java security interfaces *;

public class MD _演算法 {

private String inStr;

private MessageDigest mad ;

public MD _演算法(String inStr){

this inStr=inStr;

try{

this mad =MessageDigest getInstance( MD );

}

catch(Exception e){

System out println(e toString());

e printStackTrace();

}

}

public String pute(){

char[] charArray=this inStr toCharArray();

byte[] byteArray=new byte[charArray length];

for(int i= ;i<charArray length;i++)

byteArray[i]=(byte)charArray[i];

byte[] md Bytes=this mad digest(byteArray);

StringBuffer hexValue=new StringBuffer();

for(int i= ;i<md Bytes length;i++){

臘鬧int val=((int)md Bytes[i])& xff;

if(val< )

hexValue append( );

hexValue append(Integer toHexString(val));

}

return hexValue toString();

}

public static void main(String[] args) {

String string=null;

try{

System out println( 請輸入要加密的數據: );

BufferedReader br=new BufferedReader(new InputStreamReader(System in));

判梁string=br readLine();

掘局運}

catch(IOException e){

System out println(e);

}

MD _演算法 md =new MD _演算法(string);

String postString =pute();

System out println( 加密後的數據: +postString);

}

lishixin/Article/program/Java/hx/201311/25613

Ⅹ java 怎樣實現 64位的md5加密演算法

直接引入「commons-codec-1.10.jar」這個java包,然後調用相應方法即可

比如我們可以寫一個方法類,把常用的方法都寫進去:

publicclassEncryptionUtil{
/**
*Base64encode
**/
(Stringdata){
returnBase64.encodeBase64String(data.getBytes());
}

/**
*Base64decode
*@
**/
(Stringdata){
returnnewString(Base64.decodeBase64(data.getBytes()),"utf-8");
}

/**
*md5
**/
publicstaticStringmd5Hex(Stringdata){
returnDigestUtils.md5Hex(data);
}

/**
*sha1
**/
publicstaticStringsha1Hex(Stringdata){
returnDigestUtils.sha1Hex(data);
}

/**
*sha256
**/
publicstaticStringsha256Hex(Stringdata){
returnDigestUtils.sha256Hex(data);
}

}


(PS:純手打,望採納)

熱點內容
龍村m腳本 發布:2024-11-29 17:38:10 瀏覽:781
linuxc配置文件 發布:2024-11-29 17:08:31 瀏覽:826
wow刷碎片腳本 發布:2024-11-29 15:58:24 瀏覽:592
明小子源碼 發布:2024-11-29 15:15:30 瀏覽:144
蘋果8plus什麼配置 發布:2024-11-29 14:16:36 瀏覽:677
androidmvp結構 發布:2024-11-29 14:16:34 瀏覽:536
androidsqlite命令 發布:2024-11-29 14:04:38 瀏覽:156
信用卡分期演算法 發布:2024-11-29 13:50:56 瀏覽:808
安卓手機dll文件為什麼打不開 發布:2024-11-29 13:40:49 瀏覽:1003
百分之五十石碳酸怎麼配置 發布:2024-11-29 13:38:56 瀏覽:974