當前位置:首頁 » 操作系統 » javamd5源碼

javamd5源碼

發布時間: 2022-12-29 15:43:34

① 求一個java寫的驗證碼源碼和一個MD5加密源碼 最好粘貼過來就可以直接運行的 謝謝大神么,辛苦了

importjava.security.MessageDigest;
importjava.security.NoSuchAlgorithmException;

/*
*MD5演算法
*/
publicclassMd5Util
{

//全局數組
privatefinalstaticString[]strDigits={"0","1","2","3","4","5",
"6","7","8","9","a","b","c","d","e","f"};

publicMd5Util()
{
}

//返回形式為數字跟字元串
(bytebByte)
{
intiRet=bByte;
//System.out.println("iRet="+iRet);
if(iRet<0)
{
iRet+=256;
}
intiD1=iRet/16;
intiD2=iRet%16;
returnstrDigits[iD1]+strDigits[iD2];
}

//轉換位元組數組為16進制字串
(byte[]bByte)
{
StringBuffersBuffer=newStringBuffer();
for(inti=0;i<bByte.length;i++)
{
sBuffer.append(byteToArrayString(bByte[i]));
}
returnsBuffer.toString();
}

publicstaticStringGetMD5Code(StringstrObj)
{
StringresultString=null;
try
{
resultString=newString(strObj);
MessageDigestmd=MessageDigest.getInstance("MD5");
//md.digest()該函數返回值為存放哈希值結果的byte數組
resultString=byteToString(md.digest(strObj.getBytes()));
}catch(NoSuchAlgorithmExceptionex)
{
ex.printStackTrace();
}
returnresultString;
}

publicstaticvoidmain(String[]args)
{
System.out.println(Md5Util.GetMD5Code("99999999"));
}
}

② 跪求md5演算法的可執行程序,最好帶上流程圖和源代碼,謝了~

1. Java版MD5

MD5Util.java

[java] view plain
package com.cncounter.util.common;

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

/**
* Java消息摘要演算法 MD5 工具類,其實其他摘要演算法的實現也類似
*/
public class MD5Util {
/**
* 對文本執行 md5 摘要加密, 此演算法與 mysql,JavaScript生成的md5摘要進行過一致性對比.
* @param plainText
* @return 返回值中的字母為小寫
*/
public static String md5(String plainText) {
if (null == plainText) {
plainText = "";
}
String MD5Str = "";
try {
// JDK 6 支持以下6種消息摘要演算法,不區分大小寫
// md5,sha(sha-1),md2,sha-256,sha-384,sha-512
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();

int i;

StringBuilder builder = new StringBuilder(32);
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
builder.append("0");
builder.append(Integer.toHexString(i));
}
MD5Str = builder.toString();
// LogUtil.println("result: " + buf.toString());// 32位的加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return MD5Str;
}
// 一個簡版測試
public static void main(String[] args) {
String m1 = md5("1");
String m2 = md5(m1);
/* 輸出為
* m1=
* m2=
*/
System.out.println("m1="+m1);
System.out.println("m2="+m2);
}
}

2. MySQL版MD5

MySQL直接支持 md5函數調用
[sql] view plain
select md5('1') as m1, md5(md5('1')) as m2;

執行結果為:

[plain] view plain
MariaDB [(none)]> select md5('1') as m1, md5(md5('1')) as m2;
+----------------------------------+----------------------------------+
| m1 | m2 |
+----------------------------------+----------------------------------+
| | |
+----------------------------------+----------------------------------+
1 row in set (0.00 sec)

3. JavaScript 版MD5函數

md5.js 代碼如下:

[javascript] view plain
/*! JavaScript 的 MD5 實現 */

// 括弧表達式, (xxxxx) 是用來將內部的語句、表達式的結果作為一個結果.
// 常見的是將json字元串用 eval 解析時,需要 eval("(" +jsonstr+ ")");
// () 內部定義了一個空間, 裡面定義的變數不會污染到全局空間,很適合做lib
// (function UMD(對象/函數名name, 上下文this, 函數/對象的定義)) 返回一個匿名函數
// 因為第一個括弧內 的結果是一個函數,而函數可以這樣調用: (function(形參){})(實參);
// 這種匿名函數被瀏覽器解析後會自動執行一次.
(function UMD(name, context, definition) {
if ( typeof mole !== "undefined" && mole.exports) {
// 如果 mole 存在,並且mole.exports存在,則將賦值結果賦給 它
// 可以不用管
mole.exports = definition();
} else if ( typeof define === "function" && define.amd) {
// 如果 define 這個函數存在,應該是另一個基礎類庫,則使用define
// 可以不用管
define(definition);
} else {
// 簡單一點,可以看成: 調用傳入的definition函數,將返回的對象綁定到全局空間
// 當然,根據傳入的上下文不同,也可以綁定到其他對象下面,成為一個屬性方法.
context[name] = definition(name, context);
}
}
)("md5", this, function DEF(name, context) {"use strict";
// 上面的 use strict 表示嚴格語法模式,有錯誤就拒絕執行.
// 而普通的JS,是解釋執行,不執行的地方,有些錯誤也不影響其他代碼的執行
// 作為類庫,使用嚴格模式是很有必要的.嚴格模式聲明必須放到一個namespace空間的最起始處.

//
var old_public_api = (context || {})[name];
// 最後要返回的對象/函數.
function md5_func(text) {
return hex_md5(text);
};
// 下面一堆是具體的演算法... 可以先不用管
/////////////////////////////////////////////////////

//計算MD5
var hexcase = 0;
function hex_md5(a) {
if (a == "")
return a;
return rstr2hex(rstr_md5(str2rstr_utf8(a)))
};
function hex_hmac_md5(a, b) {
return rstr2hex(rstr_hmac_md5(str2rstr_utf8(a), str2rstr_utf8(b)))
};
function md5_vm_test() {
return hex_md5("abc").toLowerCase() == ""
};
function rstr_md5(a) {
return binl2rstr(binl_md5(rstr2binl(a), a.length * 8))
};
function rstr_hmac_md5(c, f) {
var e = rstr2binl(c);
if (e.length > 16) {
e = binl_md5(e, c.length * 8)
}
var a = Array(16), d = Array(16);
for (var b = 0; b < 16; b++) {
a[b] = e[b] ^ 909522486;
d[b] = e[b] ^ 1549556828
}
var g = binl_md5(a.concat(rstr2binl(f)), 512 + f.length * 8);
return binl2rstr(binl_md5(d.concat(g), 512 + 128))
};
function rstr2hex(c) {
try { hexcase
} catch(g) {
hexcase = 0
}
var f = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var b = "";
var a;
for (var d = 0; d < c.length; d++) {
a = c.charCodeAt(d);
b += f.charAt((a >>> 4) & 15) + f.charAt(a & 15)
}
return b
};
function str2rstr_utf8(c) {
var b = "";
var d = -1;
var a, e;
while (++d < c.length) {
a = c.charCodeAt(d);
e = d + 1 < c.length ? c.charCodeAt(d + 1) : 0;
if (55296 <= a && a <= 56319 && 56320 <= e && e <= 57343) {
a = 65536 + ((a & 1023) << 10) + (e & 1023);
d++
}
if (a <= 127) {
b += String.fromCharCode(a)
} else {
if (a <= 2047) {
b += String.fromCharCode(192 | ((a >>> 6) & 31), 128 | (a & 63))
} else {
if (a <= 65535) {
b += String.fromCharCode(224 | ((a >>> 12) & 15), 128 | ((a >>> 6) & 63), 128 | (a & 63))
} else {
if (a <= 2097151) {
b += String.fromCharCode(240 | ((a >>> 18) & 7), 128 | ((a >>> 12) & 63), 128 | ((a >>> 6) & 63), 128 | (a & 63))
}
}
}
}
}
return b
};
function rstr2binl(b) {
var a = Array(b.length >> 2);
for (var c = 0; c < a.length; c++) {
a[c] = 0
}
for (var c = 0; c < b.length * 8; c += 8) {
a[c >> 5] |= (b.charCodeAt(c / 8) & 255) << (c % 32)
}
return a
};
function binl2rstr(b) {
var a = "";
for (var c = 0; c < b.length * 32; c += 8) {
a += String.fromCharCode((b[c >> 5] >>> (c % 32)) & 255)
}
return a
};
function binl_md5(p, k) {
p[k >> 5] |= 128 << ((k) % 32);
p[(((k + 64) >>> 9) << 4) + 14] = k;
var o = 1732584193;
var n = -271733879;
var m = -1732584194;
var l = 271733878;
for (var g = 0; g < p.length; g += 16) {
var j = o;
var h = n;
var f = m;
var e = l;
o = md5_ff(o, n, m, l, p[g + 0], 7, -680876936);
l = md5_ff(l, o, n, m, p[g + 1], 12, -389564586);
m = md5_ff(m, l, o, n, p[g + 2], 17, 606105819);
n = md5_ff(n, m, l, o, p[g + 3], 22, -1044525330);
o = md5_ff(o, n, m, l, p[g + 4], 7, -176418897);
l = md5_ff(l, o, n, m, p[g + 5], 12, 1200080426);
m = md5_ff(m, l, o, n, p[g + 6], 17, -1473231341);
n = md5_ff(n, m, l, o, p[g + 7], 22, -45705983);
o = md5_ff(o, n, m, l, p[g + 8], 7, 1770035416);
l = md5_ff(l, o, n, m, p[g + 9], 12, -1958414417);
m = md5_ff(m, l, o, n, p[g + 10], 17, -42063);
n = md5_ff(n, m, l, o, p[g + 11], 22, -1990404162);
o = md5_ff(o, n, m, l, p[g + 12], 7, 1804603682);
l = md5_ff(l, o, n, m, p[g + 13], 12, -40341101);
m = md5_ff(m, l, o, n, p[g + 14], 17, -1502002290);
n = md5_ff(n, m, l, o, p[g + 15], 22, 1236535329);
o = md5_gg(o, n, m, l, p[g + 1], 5, -165796510);
l = md5_gg(l, o, n, m, p[g + 6], 9, -1069501632);
m = md5_gg(m, l, o, n, p[g + 11], 14, 643717713);
n = md5_gg(n, m, l, o, p[g + 0], 20, -373897302);
o = md5_gg(o, n, m, l, p[g + 5], 5, -701558691);
l = md5_gg(l, o, n, m, p[g + 10], 9, 38016083);
m = md5_gg(m, l, o, n, p[g + 15], 14, -660478335);
n = md5_gg(n, m, l, o, p[g + 4], 20, -405537848);
o = md5_gg(o, n, m, l, p[g + 9], 5, 568446438);
l = md5_gg(l, o, n, m, p[g + 14], 9, -1019803690);
m = md5_gg(m, l, o, n, p[g + 3], 14, -187363961);
n = md5_gg(n, m, l, o, p[g + 8], 20, 1163531501);
o = md5_gg(o, n, m, l, p[g + 13], 5, -1444681467);
l = md5_gg(l, o, n, m, p[g + 2], 9, -51403784);
m = md5_gg(m, l, o, n, p[g + 7], 14, 1735328473);
n = md5_gg(n, m, l, o, p[g + 12], 20, -1926607734);
o = md5_hh(o, n, m, l, p[g + 5], 4, -378558);
l = md5_hh(l, o, n, m, p[g + 8], 11, -2022574463);
m = md5_hh(m, l, o, n, p[g + 11], 16, 1839030562);
n = md5_hh(n, m, l, o, p[g + 14], 23, -35309556);
o = md5_hh(o, n, m, l, p[g + 1], 4, -1530992060);
l = md5_hh(l, o, n, m, p[g + 4], 11, 1272893353);
m = md5_hh(m, l, o, n, p[g + 7], 16, -155497632);
n = md5_hh(n, m, l, o, p[g + 10], 23, -1094730640);
o = md5_hh(o, n, m, l, p[g + 13], 4, 681279174);
l = md5_hh(l, o, n, m, p[g + 0], 11, -358537222);
m = md5_hh(m, l, o, n, p[g + 3], 16, -722521979);
n = md5_hh(n, m, l, o, p[g + 6], 23, 76029189);

③ md5生成64個字元串的java代碼

Md5PasswordEncoder md5=new Md5PasswordEncoder();
String md5Password=md5.encodePassword(string null);

④ JAVA簡單文件加密 求JAVA源代碼

md5加密:
package com.ncs.pki.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Test {
private static MessageDigest digest = null;
public synchronized static final String hash(String data) {
if (digest == null) {
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException nsae) {
System.err.println(
"Failed to load the MD5 MessageDigest. "
+ "Jive will be unable to function normally.");
nsae.printStackTrace();
}
}
// Now, compute hash.
digest.update(data.getBytes());
return encodeHex(digest.digest());
}
public static final String encodeHex(byte[] bytes) {
StringBuffer buf = new StringBuffer(bytes.length * 2);
int i;

for (i = 0; i < bytes.length; i++) {
if (((int) bytes[i] & 0xff) < 0x10) {
buf.append("0");
}
buf.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buf.toString();
}
public static String test(){
return null;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(MD5Test.hash("123456"));
}

}

3des加密:
package com.ncs.pki.util;

import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class DesEncrypt {
/**
*
* 使用DES加密與解密,可對byte[],String類型進行加密與解密 密文可使用String,byte[]存儲.
*
* 方法: void getKey(String strKey)從strKey的字條生成一個Key
*
* String getEncString(String strMing)對strMing進行加密,返回String密文 String
* getDesString(String strMi)對strMin進行解密,返回String明文
*
*byte[] getEncCode(byte[] byteS)byte[]型的加密 byte[] getDesCode(byte[]
* byteD)byte[]型的解密
*/

Key key;

/**
* 根據參數生成KEY
*
* @param strKey
*/
public void getKey(String strKey) {
try {
KeyGenerator _generator = KeyGenerator.getInstance("DES");
_generator.init(new SecureRandom(strKey.getBytes()));
this.key = _generator.generateKey();
_generator = null;
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 加密String明文輸入,String密文輸出
*
* @param strMing
* @return
*/
public String getEncString(String strMing) {

byte[] byteMi = null;
byte[] byteMing = null;
String strMi = "";
BASE64Encoder base64en = new BASE64Encoder();
try {
byteMing = strMing.getBytes("UTF8");
byteMi = this.getEncCode(byteMing);
strMi = base64en.encode(byteMi);
} catch (Exception e) {
e.printStackTrace();
} finally {
base64en = null;
byteMing = null;
byteMi = null;
}
return strMi;
}

/**
* 解密 以String密文輸入,String明文輸出
*
* @param strMi
* @return
*/
public String getDesString(String strMi) {
BASE64Decoder base64De = new BASE64Decoder();
byte[] byteMing = null;
byte[] byteMi = null;
String strMing = "";
try {
byteMi = base64De.decodeBuffer(strMi);
byteMing = this.getDesCode(byteMi);
strMing = new String(byteMing, "UTF8");
} catch (Exception e) {
e.printStackTrace();
} finally {
base64De = null;
byteMing = null;
byteMi = null;
}
return strMing;
}

/**
* 加密以byte[]明文輸入,byte[]密文輸出
*
* @param byteS
* @return
*/
private byte[] getEncCode(byte[] byteS) {
byte[] byteFina = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byteFina = cipher.doFinal(byteS);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}

/**
* 解密以byte[]密文輸入,以byte[]明文輸出
*
* @param byteD
* @return
*/
private byte[] getDesCode(byte[] byteD) {
Cipher cipher;
byte[] byteFina = null;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byteFina = cipher.doFinal(byteD);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}

public static void main(String[] args) {
System.out.println("des demo");
DesEncrypt des = new DesEncrypt();// 實例化一個對像
des.getKey("MYKEY");// 生成密匙
System.out.println("key=MYKEY");
String strEnc = des.getEncString("111111");// 加密字元串,返回String的密文
System.out.println("密文=" + strEnc);
String strDes = des.getDesString(strEnc);// 把String 類型的密文解密
System.out.println("明文=" + strDes);
}
}

⑤ java生成的MD5,和c#的生成的不一致,有java代碼,求c#代碼!

考慮一下中文字元問題。兩邊使用的編碼是不是一樣的。保持一樣就可以了。

建議使用UTF8編碼


JAVA代碼如下(在你給同的代碼上只做了少量修改):

publicclassSecurity{

publicstaticvoidmain(String[]args){
try{
System.out.println(MD5("中國"));
}catch(Exceptionex){}
}

publicstaticStringMD5(Stringtxt){
charhexDigits[]={'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f'};
try{
byte[]btInput=txt.getBytes("utf-8");
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;
}
}
}


C#代碼如下:

staticvoidMain(string[]args)
{
Console.WriteLine(Md5("中國"));
Console.ReadLine();
}

staticstringMd5(stringtxt){
byte[]result=Encoding.UTF8.GetBytes(txt);
MD5md5=newMD5CryptoServiceProvider();
byte[]output=md5.ComputeHash(result);
returnBitConverter.ToString(output).Replace("-","");
}

⑥ 求java加密源代碼(MD5,base64)

import java.security.*;
import javax.crypto.*;

/**
* 本例解釋如何利用DES私鑰加密演算法加解密
*
* @author Devon
* @version 1.0 04/03/10
*/
public class SingleKeyExample {

public static void main(String[] args) {
try {
String algorithm = "DES"; //定義加密演算法,可用 DES,DESede,Blowfish
String message = "Hello World. 這是待加密的信息";

// 生成個DES密鑰
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
keyGenerator.init(56); //選擇DES演算法,密鑰長度必須為56位
Key key = keyGenerator.generateKey(); //生成密鑰

// 生成Cipher對象
Cipher cipher = Cipher.getInstance("DES");

//用密鑰加密明文(message),生成密文(cipherText)
cipher.init(Cipher.ENCRYPT_MODE, key); //操作模式為加密(Cipher.ENCRYPT_MODE),key為密鑰
byte[] cipherText = cipher.doFinal(message.getBytes()); //得到加密後的位元組數組
System.out.println("加密後的信息: " + new String(cipherText));

//用密鑰加密明文(plainText),生成密文(cipherByte)
cipher.init(Cipher.DECRYPT_MODE, key); //操作模式為解密,key為密鑰
byte[] sourceText = cipher.doFinal(cipherText); //獲得解密後位元組數組
System.out.println("解密後的信息: " + new String(sourceText));
} catch (Exception ex) {
ex.printStackTrace();
}
}

}

/**
* @author Devon
*/

import java.security.*;
import java.security.spec.*;
import javax.crypto.*;

public class PairKeyExample {

public static void main(String argv[]) {
try {
String algorithm = "RSA"; //定義加密演算法,可用 DES,DESede,Blowfish
String message = "張三,你好,我是李四";

//產生張三的密鑰對(keyPairZhang)
KeyPairGenerator keyGeneratorZhang =
KeyPairGenerator.getInstance(algorithm); //指定採用的演算法
keyGeneratorZhang.initialize(1024); //指定密鑰長度為1024位
KeyPair keyPairZhang = keyGeneratorZhang.generateKeyPair(); //產生密鑰對
System.out.println("生成張三的公鑰對");

// 張三生成公鑰(publicKeyZhang)並發送給李四,這里發送的是公鑰的數組位元組
byte[] publicKeyZhangEncode = keyPairZhang.getPublic().getEncoded();

//通過網路或磁碟等方式,把公鑰編碼傳送給李四
//李四接收到張三編碼後的公鑰,將其解碼
KeyFactory keyFacoryLi = KeyFactory.getInstance(algorithm); //得到KeyFactory對象
X509EncodedKeySpec x509KeySpec =
new X509EncodedKeySpec(publicKeyZhangEncode); //公鑰採用X.509編碼
PublicKey publicKeyZhang = keyFacoryLi.generatePublic(x509KeySpec); //將公鑰的KeySpec對象轉換為公鑰
System.out.println("李四成功解碼,得到張三的公鑰");

//李四用張三的公鑰加密信息,並發送給李四
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); //得到Cipher對象
cipher.init(Cipher.ENCRYPT_MODE, publicKeyZhang); //用張三的公鑰初始化Cipher對象
byte[] cipherMessage = cipher.doFinal(message.getBytes()); //得到加密信息
System.out.println("加密後信息:" + new String(cipherMessage));
System.out.println("加密完成,發送給李四...");

//張三用自己的私鑰解密從李四處收到的信息
cipher.init(Cipher.DECRYPT_MODE, keyPairZhang.getPrivate()); //張三用其私鑰初始化Cipher對象
byte[] originalMessage = cipher.doFinal(cipherMessage); //得到解密後信息
System.out.println("張三收到信息,解密後為:" + new String(originalMessage));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

⑦ java中用MessageDigest包實現MD5功能出亂碼

這里肯定會出亂碼的,必需將得到的位元組碼再次進行編碼,一般是16進制編碼。
如:
byte []bytes=md5.digest(user.getPassword().getBytes("utf8"));
StringBuilder ret=new StringBuilder(bytes.length<<1);
for(int i=0;i<bytes.length;i++){
ret.append(Character.forDigit((bytes[i]>>4)&0xf,16));
ret.append(Character.forDigit(bytes[i]&0xf,16));
}
user.setPassword(ret.toString());

⑧ MD5的Java Bean實現

MD 簡介 MD 的全稱是Message Digest Algorithm 在 年代初由MIT的計算機科學實驗室和RSA Data Security Inc發明 經MD MD 和MD 發展而來 Message Digest泛指位元組串(Message)的Hash變換 就是把一個任意長度的位元組串變換成一定長的大整數 請注意我使用了 位元組串 而不是 字元串 這個詞 是因為這種變換只與位元組的值有關 與字元集或編碼方式無關 MD 將任意長度的 位元組串 變換成一個 bit的大整數 並且它是一個不可逆的字元串變換演算法 換句話說就是 即使你看到源程序和演算法描述 也無法將一個MD 的值變換回原始的字元串 從數學原理上說 是因為原始的字元串有無窮多個 這有點象不存在反函數的數學函數 MD 的典型應用是對一段Message(位元組串)產生fingerprint(指紋) 以防止被 篡改 舉個例子 你將一段話寫在一個叫readme txt文件中 並對這個readme txt產生一個MD 的值並記錄在案 然後你可以傳播這個文件給別人 別人如果修改了文件中的任何內容 你對這個文件重新計算MD 時就會發現 如果再有一個第三方的認證機構 用MD 還可以防止文件作者的 抵賴 這就是所謂的數字簽名應用 MD 還廣泛用於加密和解密技術上 在很多操作系統中 用戶的密碼是以MD 值(或類似的其它演算法)的方式保存的 用戶Login的時候 系統是把用戶輸入的密碼計算成MD 值 然後再去和系統中保存的MD 值進行比較 而系統並不 知道 用戶的密碼是什麼 一些黑客破獲這種密碼的方法是一種被稱為 跑字典 的方法 有兩種方法得到字典 一種是日常搜集的用做密碼的字元串表 另一種是用排列組合方法生成的 先用MD 程序計算出這些字典項的MD 值 然後再用目標的MD 值在這個字典中檢索 即使假設密碼的最大長度為 同時密碼只能是字母和數字 共 + + = 個字元 排列組合出的字典的項數則是P( )+P( )… +P( ) 那也已經是一個很天文的數字了 存儲這個字典就需要TB級的磁碟組 而且這種方法還有一個前提 就是能獲得目標賬戶的密碼MD 值的情況下才可以 在很多電子商務和社區應用中 管理用戶的Account是一種最常用的基本功能 盡管很多Application Server提供了這些基本組件 但很多應用開發者為了管理的更大的靈活性還是喜歡採用關系資料庫來管理用戶 懶惰的做法是用戶的密碼往往使用明文或簡單的變換後直接保存在資料庫中 因此這些用戶的密碼對軟體開發者或系統管理員來說可以說毫無保密可言 本文的目的是介紹MD 的Java Bean的實現 同時給出用MD 來處理用戶的Account密碼的例子 這種方法使得管理員和程序設計者都無法看到用戶的密碼 盡管他們可以初始化它們 但重要的一點是對於用戶密碼設置習慣的保護 有興趣的讀者可以從這里取得MD 也就是RFC 的文本 實現策略 MD 的演算法在RFC 中實際上已經提供了C的實現 我們其實馬上就能想到 至少有兩種用Java實現它的方法 第一種是 用Java語言重新寫整個演算法 或者再說簡單點就是把C程序改寫成Java程序 第二種是 用JNI(Java Native Interface)來實現 核心演算法仍然用這個C程序 用Java類給它包個殼 但我個人認為 JNI應該是Java為了解決某類問題時的沒有辦法的辦法(比如與操作系統或I/O設備密切相關的應用) 同時為了提供和其它語言的互操作性的一個手段 使用JNI帶來的最大問題是引入了平台的依賴性 打破了SUN所鼓吹的 一次編寫到處運行 的Java好處 因此 我決定採取第一種方法 一來和大家一起嘗試一下 一次編寫到處運行 的好處 二來檢驗一下Java 現在對於比較密集的計算的效率問題 實現過程 限於這篇文章的篇幅 同時也為了更多的讀者能夠真正專注於問題本身 我不想就某一種Java集成開發環境來介紹這個Java Bean的製作過程 介紹一個方法時我發現步驟和命令很清晰 我相信有任何一種Java集成環境三天以上經驗的讀者都會知道如何把這些代碼在集成環境中編譯和運行 用集成環境講述問題往往需要配很多屏幕截圖 這也是我一直對集成環境很頭疼的原因 我使用了一個普通的文本編輯器 同時使用了Sun公司標準的JDK for Windows NT 其實把C轉換成Java對於一個有一定C語言基礎的程序員並不困難 這兩個語言的基本語法幾乎完全一致.我大概花了一個小時的時間完成了代碼的轉換工作 我主要作了下面幾件事 把必須使用的一些#define的宏定義變成Class中的final static 這樣保證在一個進程空間中的多個Instance共享這些數據 刪去了一些無用的#if define 因為我只關心MD 這個推薦的C實現同時實現了MD MD 和 MD 而且有些#if define還和C不同編譯器有關 將一些計算宏轉換成final static 成員函數 所有的變數命名與原來C實現中保持一致 在大小寫上作一些符合Java習慣的變化 計算過程中的C函數變成了private方法(成員函數) 關鍵變數的位長調整 定義了類和方法需要注意的是 很多早期的C編譯器的int類型是 bit的 MD 使用了unsigned long int 並認為它是 bit的無符號整數 而在Java中int是 bit的 long是 bit的 在MD 的C實現中 使用了大量的位操作 這里需要指出的一點是 盡管Java提供了位操作 由於Java沒有unsigned類型 對於右移位操作多提供了一個無符號右移 >>> 等價於C中的 >> 對於unsigned 數的處理 因為Java不提供無符號數的運算 兩個大int數相加就會溢出得到一個負數或異常 因此我將一些關鍵變數在Java中改成了long類型( bit) 我個人認為這比自己去重新定義一組無符號數的類同時重載那些運算符要方便 同時效率高很多並且代碼也易讀 OO(Object Oriented)的濫用反而會導致效率低下 限於篇幅 這里不再給出原始的C代碼 有興趣對照的讀者朋友可以去看RFC MD java源代碼 測試 在RFC 中 給出了Test suite用來檢驗你的實現是否正確 MD ( ) = d d cd f b e ecf e MD ( a ) = cc b c f b a c e MD ( abc ) = cd fb d f d e f MD ( message digest ) = f b d cb d a f aaf d MD ( abcdefghijklmnopqrstuvwxyz ) = c fcd d e dfb cca e b …… 這些輸出結果的含義是指 空字元串 的MD 值是d d cd f b e ecf e 字元串 a 的MD 值是 cc b c f b a c e …… 編譯並運行我們的程序 javac –d MD javajava beartool MD 為了將來不與別人的同名程序沖突 我在我的程序的第一行使用了package beartool; 因此編譯命令javac –d MD java 命令在我們的工作目錄下自動建立了一個beartool目錄 目錄下放著編譯成功的 MD class 我們將得到和Test suite同樣的結果 當然還可以繼續測試你感興趣的其它MD 變換 例如 java beartool MD 將給出 的MD 值 可能是我的計算機知識是從Apple II和Z 單板機開始的 我對大寫十六進制代碼有偏好 如果您想使用小寫的Digest String只需要把byteHEX函數中的A B C D E F改成a b c d e f就可以了 MD 據稱是一種比較耗時的計算 我們的Java版MD 一閃就算出來了 沒遇到什麼障礙 而且用肉眼感覺不出來Java版的MD 比C版的慢 為了測試它的兼容性 我把這個MD class文件拷貝到我的另一台Linux+IBM JDK 的機器上 執行後得到同樣結果 確實是 一次編寫到處運行了 Java Bean簡述 現在 我們已經完成並簡單測試了這個Java Class 我們文章的標題是做一個Java Bean 其實普通的Java Bean很簡單 並不是什麼全新的或偉大的概念 就是一個Java的Class 盡管 Sun規定了一些需要實現的方法 但並不是強制的 而EJB(Enterprise Java Bean)無非規定了一些必須實現(非常類似於響應事件)的方法 這些方法是供EJB Container使用(調用)的 在一個Java Application或Applet里使用這個bean非常簡單 最簡單的方法是你要使用這個類的源碼工作目錄下建一個beartool目錄 把這個class文件拷貝進去 然後在你的程序中import beartool MD 就可以了 最後打包成 jar或 war是保持這個相對的目錄關系就行了 lishixin/Article/program/Java/hx/201311/26240

⑨ 如何使用Java生成MD5代碼

這是我以前做的一個小項目時用到md5寫的


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

//將用戶密碼進行md5加密 並返回加密後的32位十六進制密碼

public class MD5Util {
public static String md5(String password) {

try {
// 獲取md5對象
MessageDigest md = MessageDigest.getInstance("md5");
// 獲取加密後的密碼並返回十進制位元組數組
byte[] bytes = md.digest(password.getBytes());

// 遍歷數組得到每個十進制數並轉換成十六進制

StringBuffer sb = new StringBuffer();
for (byte b : bytes) {

// 把每個數轉成十六進制 存進字元中
sb.append(toHex(b));
}
String finish = sb.toString();
return finish;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException(e);
}

}

// 十進制轉十六進制方法
private static String toHex(byte b) {

int target = 0;

if (b < 0) {
target = 255 + b;
} else {
target = b;
}

int first = target / 16;
int second = target % 16;

return Hex[first] + Hex[second];
}

static String[] Hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"a", "b", "c", "d", "e", "f" };

/*public static void main(String[] args) {
String a = MD5Util.md5("1234");
System.out.println(a);
}*/
}

⑩ 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]));

}
}

熱點內容
銀行推薦演算法 發布:2025-05-10 16:57:21 瀏覽:641
2014年二級c語言真題 發布:2025-05-10 16:56:25 瀏覽:179
絕地求生進不去顯示伺服器已滿怎麼辦 發布:2025-05-10 16:56:21 瀏覽:89
存儲系統安裝工程師 發布:2025-05-10 16:53:38 瀏覽:708
php搜索分詞 發布:2025-05-10 16:53:29 瀏覽:546
8位加密 發布:2025-05-10 16:51:01 瀏覽:651
免費nvr伺服器搭建 發布:2025-05-10 16:45:20 瀏覽:847
宏傑文件夾加密怎麼樣 發布:2025-05-10 16:40:16 瀏覽:507
我的世界java伺服器種子 發布:2025-05-10 16:38:51 瀏覽:273
linux做存儲伺服器要什麼配置 發布:2025-05-10 16:26:39 瀏覽:430