Có phương pháp nào để tạo băm MD5 của một chuỗi trong Java không?
Có phương pháp nào để tạo băm MD5 của một chuỗi trong Java không?
Câu trả lời:
Bạn cần java.security.MessageDigest
.
Gọi MessageDigest.getInstance("MD5")
để có được một ví dụ MD5 của MessageDigest
bạn có thể sử dụng.
Việc tính toán hàm băm bằng cách thực hiện một trong các:
byte[]
và tính toán hàm băm trong một thao tác với md.digest(bytes)
.MessageDigest
một byte[]
miếng một lúc bằng cách gọi md.update(bytes)
. Khi bạn hoàn thành việc thêm byte đầu vào, hãy tính băm với
md.digest()
.Trả byte[]
về bởi md.digest()
hàm băm MD5.
MessageDigest
cho phép bạn nhập dữ liệu theo từng khối. Điều đó sẽ không thể xảy ra với một phương pháp tĩnh. Mặc dù bạn có thể tranh luận rằng dù sao họ cũng nên thêm một cái để thuận tiện khi bạn có thể truyền tất cả dữ liệu cùng một lúc.
Các MessageDigest
lớp có thể cung cấp cho bạn với một thể hiện của các MD5 tiêu hóa.
Khi làm việc với các chuỗi và các lớp mật mã, hãy đảm bảo luôn chỉ định mã hóa mà bạn muốn biểu diễn byte. Nếu bạn chỉ sử dụng string.getBytes()
nó sẽ sử dụng mặc định nền tảng. (Không phải tất cả các nền tảng đều sử dụng cùng một giá trị mặc định)
import java.security.*;
..
byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);
Nếu bạn có nhiều dữ liệu, hãy xem .update(byte[])
phương pháp có thể được gọi nhiều lần. Sau đó gọi .digest()
để có được băm kết quả.
yourString.getBytes(StandardCharsets.UTF_8)
. Điều này ngăn chặn xử lý một UnsupportedEncodingException
.
Nếu bạn thực sự muốn câu trả lời trở lại dưới dạng một chuỗi trái ngược với một mảng byte, bạn luôn có thể làm một cái gì đó như thế này:
String plaintext = "your text here";
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());
byte[] digest = m.digest();
BigInteger bigInt = new BigInteger(1,digest);
String hashtext = bigInt.toString(16);
// Now we need to zero pad it if you actually want the full 32 chars.
while(hashtext.length() < 32 ){
hashtext = "0"+hashtext;
}
hashtext = "0".repeat(32 - hashtext.length()) + hashtext
thay vì while
, vì vậy các trình soạn thảo sẽ không đưa ra cảnh báo rằng bạn đang thực hiện nối chuỗi trong một vòng lặp.
Bạn cũng có thể muốn xem lớp DigestUtils của dự án codec apache commons , cung cấp các phương thức rất thuận tiện để tạo ra các bản tóm tắt MD5 hoặc SHA.
Tìm thấy điều này:
public String MD5(String md5) {
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(md5.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; ++i) {
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
}
return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) {
}
return null;
}
trên trang web dưới đây, tôi không tin tưởng vào nó, nhưng đó là một giải pháp hiệu quả! Đối với tôi rất nhiều mã khác không hoạt động chính xác, cuối cùng tôi đã bỏ lỡ 0 số trong hàm băm. Cái này có vẻ giống như PHP. nguồn: http://m2tec.be/blog/2010/02/03/java-md5-hex-0093
getBytes()
, nếu không, mã của bạn sẽ nhận được các kết quả khác nhau trên các cài đặt người dùng / nền tảng khác nhau.
byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8")));
Đây là cách tôi sử dụng nó:
final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(string.getBytes(Charset.forName("UTF8")));
final byte[] resultByte = messageDigest.digest();
final String result = new String(Hex.encodeHex(resultByte));
Trong đó Hex là: org.apache.commons.codec.binary.Hex
từ dự án Apache Commons .
String result = Hex.encodeHexString(resultByte);
Tôi vừa tải xuống commons-codec.jar và nhận được php hoàn hảo như md5. Đây là hướng dẫn .
Chỉ cần nhập nó vào dự án của bạn và sử dụng
String Url = "your_url";
System.out.println( DigestUtils.md5Hex( Url ) );
Và bạn có nó rồi đấy.
Tôi đã thấy đây là cách rõ ràng và ngắn gọn nhất để làm điều đó:
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(StandardCharsets.UTF_8.encode(string));
return String.format("%032x", new BigInteger(1, md5.digest()));
Đã tìm thấy giải pháp này sạch hơn nhiều về việc lấy lại đại diện Chuỗi từ hàm băm MD5.
import java.security.*;
import java.math.*;
public class MD5 {
public static void main(String args[]) throws Exception{
String s="This is a test";
MessageDigest m=MessageDigest.getInstance("MD5");
m.update(s.getBytes(),0,s.length());
System.out.println("MD5: "+new BigInteger(1,m.digest()).toString(16));
}
}
Mã được trích xuất từ đây .
String.format("%032x", new BigInteger(1, hash));
Điều này sẽ giải quyết điều này. 'Băm' là byte [] của hàm băm.
Một lựa chọn khác là sử dụng các phương pháp băm Guava :
Hasher hasher = Hashing.md5().newHasher();
hasher.putString("my string");
byte[] md5 = hasher.hash().asBytes();
Tiện dụng nếu bạn đã sử dụng Guava (nếu bạn không dùng, có lẽ bạn nên dùng).
Hashing.md5().hashString("my string").asBytes();
Một cách thực hiện khác:
import javax.xml.bind.DatatypeConverter;
String hash = DatatypeConverter.printHexBinary(
MessageDigest.getInstance("MD5").digest("SOMESTRING".getBytes("UTF-8")));
Tôi có Class (Hash) để chuyển đổi văn bản đơn giản thành hàm băm theo các định dạng: md5 hoặc sha1, simillar mà hàm php ( md5 , sha1 ):
public class Hash {
/**
*
* @param txt, text in plain format
* @param hashType MD5 OR SHA1
* @return hash in hashType
*/
public static String getHash(String txt, String hashType) {
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance(hashType);
byte[] array = md.digest(txt.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; ++i) {
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
}
return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) {
//error action
}
return null;
}
public static String md5(String txt) {
return Hash.getHash(txt, "MD5");
}
public static String sha1(String txt) {
return Hash.getHash(txt, "SHA1");
}
}
<?php
echo 'MD5 :' . md5('Hello World') . "\n";
echo 'SHA1:' . sha1('Hello World') . "\n";
MD5 :b10a8db164e0754105b7a99be72e3fe5
SHA1:0a4d55a8d778e5022fab701977c5d840bbc486d0
public class HashTest {
@Test
public void test() {
String txt = "Hello World";
assertEquals("b10a8db164e0754105b7a99be72e3fe5", Hash.md5(txt));
assertEquals("0a4d55a8d778e5022fab701977c5d840bbc486d0", Hash.sha1(txt));
}
}
Không cần phải làm cho nó quá phức tạp.
DigestUtils hoạt động tốt và làm cho bạn thoải mái khi làm việc với md5
băm.
DigestUtils.md5Hex(_hash);
hoặc là
DigestUtils.md5(_hash);
Bạn có thể sử dụng bất kỳ phương thức mã hóa nào khác như sha
hoặc md
.
Câu trả lời không tiết lộ của tôi:
private String md5(String s) {
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(s.getBytes(), 0, s.length());
BigInteger i = new BigInteger(1,m.digest());
return String.format("%1$032x", i);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
String.format("%1$032X", big)
để có một định dạng chữ hoa
Bạn có thể thử làm theo. Xem chi tiết và mã tải xuống tại đây: http://jkssweetlife.com/java-hashgenerator-md5-sha-1/
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Example {
public static void main(String[] args) throws Exception {
final String inputString = "Hello MD5";
System.out.println("MD5 hex for '" + inputString + "' :");
System.out.println(getMD5Hex(inputString));
}
public static String getMD5Hex(final String inputString) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(inputString.getBytes());
byte[] digest = md.digest();
return convertByteToHex(digest);
}
private static String convertByteToHex(byte[] byteData) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
}
Câu trả lời của Bombe là chính xác, tuy nhiên lưu ý rằng trừ khi bạn hoàn toàn phải sử dụng MD5 (ví dụ bắt buộc bạn phải có khả năng tương tác), một lựa chọn tốt hơn là SHA1 vì MD5 có điểm yếu khi sử dụng lâu dài.
Tôi nên thêm rằng SHA1 cũng có lỗ hổng lý thuyết, nhưng không nghiêm trọng. Tình trạng hiện tại của nghệ thuật băm là có một số hàm băm thay thế ứng viên nhưng chưa có hàm nào là tiêu chuẩn thực hành tốt nhất để thay thế SHA1. Vì vậy, tùy thuộc vào nhu cầu của bạn, bạn sẽ được khuyên nên làm cho thuật toán băm của mình có thể cấu hình để có thể thay thế nó trong tương lai.
Một triển khai khác: Triển khai MD5 nhanh trong Java
String hash = MD5.asHex(MD5.getHash(new File(filename)));
Tôi không biết điều này có phù hợp với bất kỳ ai đọc nó không, nhưng tôi chỉ gặp vấn đề mà tôi muốn
Tôi chỉ muốn làm điều đó với các lớp JRE (không có Apache Commons hoặc tương tự). Một tìm kiếm trên web nhanh không hiển thị cho tôi các đoạn mã mẫu thực hiện cả hai cùng một lúc, chỉ mỗi nhiệm vụ riêng biệt. Bởi vì điều này đòi hỏi phải đọc cùng một tệp hai lần, tôi cho rằng có thể đáng để viết một số mã hợp nhất cả hai tác vụ, tính toán tổng kiểm tra khi đang tải xuống tệp. Đây là kết quả của tôi (xin lỗi nếu nó không phải là Java hoàn hảo, nhưng tôi đoán dù sao bạn cũng hiểu ý tưởng đó):
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.security.DigestOutputStream; // new
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
void downloadFile(String fromURL, String toFile, BigInteger md5)
throws IOException, NoSuchAlgorithmException
{
ReadableByteChannel in = Channels.newChannel(new URL(fromURL).openStream());
MessageDigest md5Digest = MessageDigest.getInstance("MD5");
WritableByteChannel out = Channels.newChannel(
//new FileOutputStream(toFile)); // old
new DigestOutputStream(new FileOutputStream(toFile), md5Digest)); // new
ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024); // 1 MB
while (in.read(buffer) != -1) {
buffer.flip();
//md5Digest.update(buffer.asReadOnlyBuffer()); // old
out.write(buffer);
buffer.clear();
}
BigInteger md5Actual = new BigInteger(1, md5Digest.digest());
if (! md5Actual.equals(md5))
throw new RuntimeException(
"MD5 mismatch for file " + toFile +
": expected " + md5.toString(16) +
", got " + md5Actual.toString(16)
);
}
Hãy xem liên kết sau, Ví dụ nhận được MD5 Hash của hình ảnh được cung cấp: MD5 Hash của một hình ảnh
Để biết giá trị của nó, tôi đã vấp phải điều này vì tôi muốn tổng hợp GUID từ một khóa tự nhiên cho một chương trình sẽ cài đặt các thành phần COM; Tôi muốn tổng hợp để không quản lý vòng đời GUID. Tôi sẽ sử dụng MD5 và sau đó sử dụng lớp UUID để lấy một chuỗi ra khỏi nó. (http://stackoverflow.com/questions/2190890/how-can-i-generate-guid-for-a-opes-values/12867439 đặt ra vấn đề này).
Trong mọi trường hợp, java.util.UUID có thể giúp bạn có được một Chuỗi đẹp từ các byte MD5.
return UUID.nameUUIDFromBytes(md5Bytes).toString();
MessageDigest
(xem mã nguồn nameUUIDFromBytes () )
import java.security.*;
import javax.xml.bind.*;
byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytesOfDigest = md.digest(bytesOfMessage);
String digest = DatatypeConverter.printHexBinary(bytesOfDigest).toLowerCase();
Không giống như PHP nơi bạn có thể thực hiện băm MD5 văn bản của mình bằng cách chỉ gọi hàm md5 tức là md5($text)
, trong Java, nó được thực hiện hơi phức tạp. Tôi thường thực hiện nó bằng cách gọi một hàm trả về văn bản băm md5. Đây là cách tôi triển khai nó, Đầu tiên hãy tạo một hàm có tên md5hashing
bên trong lớp chính của bạn như được đưa ra dưới đây.
public static String md5hashing(String text)
{ String hashtext = null;
try
{
String plaintext = text;
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());
byte[] digest = m.digest();
BigInteger bigInt = new BigInteger(1,digest);
hashtext = bigInt.toString(16);
// Now we need to zero pad it if you actually want the full 32 chars.
while(hashtext.length() < 32 ){
hashtext = "0"+hashtext;
}
} catch (Exception e1)
{
// TODO: handle exception
JOptionPane.showMessageDialog(null,e1.getClass().getName() + ": " + e1.getMessage());
}
return hashtext;
}
Bây giờ gọi hàm bất cứ khi nào bạn cần như được đưa ra dưới đây.
String text = textFieldName.getText();
String pass = md5hashing(text);
Ở đây bạn có thể thấy rằng hashtext được gắn thêm số 0 để làm cho nó khớp với băm md5 trong PHP.
MD5 hoàn toàn ổn nếu bạn không cần bảo mật tốt nhất và nếu bạn đang làm gì đó như kiểm tra tính toàn vẹn của tệp thì bảo mật không phải là vấn đề cần cân nhắc. Trong trường hợp như bạn có thể muốn xem xét một cái gì đó đơn giản và nhanh hơn, chẳng hạn như Adler32, cũng được các thư viện Java hỗ trợ.
cái này cung cấp cho md5 chính xác khi bạn nhận được từ hàm md5 của mysql hoặc các hàm md5 của php, v.v ... Đây là cái tôi sử dụng (bạn có thể thay đổi theo nhu cầu của bạn)
public static String md5( String input ) {
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(input.getBytes( "UTF-8" ));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; i++) {
sb.append( String.format( "%02x", array[i]));
}
return sb.toString();
} catch ( NoSuchAlgorithmException | UnsupportedEncodingException e) {
return null;
}
}
thử cái này:
public static String getHashMD5(String string) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
BigInteger bi = new BigInteger(1, md.digest(string.getBytes()));
return bi.toString(16);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(MD5Utils.class
.getName()).log(Level.SEVERE, null, ex);
return "";
}
}
import java.security.MessageDigest
val digest = MessageDigest.getInstance("MD5")
//Quick MD5 of text
val text = "MD5 this text!"
val md5hash1 = digest.digest(text.getBytes).map("%02x".format(_)).mkString
//MD5 of text with updates
digest.update("MD5 ".getBytes())
digest.update("this ".getBytes())
digest.update("text!".getBytes())
val md5hash2 = digest.digest().map(0xFF & _).map("%02x".format(_)).mkString
//Output
println(md5hash1 + " should be the same as " + md5hash2)
Bạn có thể tạo băm MD5 cho một văn bản nhất định bằng cách sử dụng các phương thức trong MessageDigest
lớp trong java.security
gói. Dưới đây là đoạn mã hoàn chỉnh,
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;
public class MD5HashGenerator
{
public static void main(String args[]) throws NoSuchAlgorithmException
{
String stringToHash = "MyJavaCode";
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(stringToHash.getBytes());
byte[] digiest = messageDigest.digest();
String hashedOutput = DatatypeConverter.printHexBinary(digiest);
System.out.println(hashedOutput);
}
}
Đầu ra từ hàm MD5 là hàm băm 128 bit được biểu thị bằng 32 số thập lục phân.
Trong trường hợp, nếu bạn đang sử dụng một cơ sở dữ liệu như MySQL, bạn cũng có thể làm điều này theo cách đơn giản hơn. Truy vấn Select MD5(“text here”)
sẽ trả về hàm băm MD5 của văn bản trong ngoặc.
Đây là những gì tôi đến đây - một hàm scala tiện dụng trả về chuỗi băm MD5:
def md5(text: String) : String = java.security.MessageDigest.getInstance("MD5").digest(text.getBytes()).map(0xFF & _).map { "%02x".format(_) }.foldLeft(""){_ + _}
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* MD5 encryption
*
* @author Hongten
*
*/
public class MD5 {
public static void main(String[] args) {
System.out.println(MD5.getMD5("123456"));
}
/**
* Use md5 encoded code value
*
* @param sInput
* clearly
* @ return md5 encrypted password
*/
public static String getMD5(String sInput) {
String algorithm = "";
if (sInput == null) {
return "null";
}
try {
algorithm = System.getProperty("MD5.algorithm", "MD5");
} catch (SecurityException se) {
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
byte buffer[] = sInput.getBytes();
for (int count = 0; count < sInput.length(); count++) {
md.update(buffer, 0, count);
}
byte bDigest[] = md.digest();
BigInteger bi = new BigInteger(bDigest);
return (bi.toString(16));
}
}
Có một bài viết về Codingkit về điều đó. Kiểm tra: http://codingkit.com/a/JAVA/2013/1020/2216.html