Reputation: 13
i try to ganerate md5 string in java.I wrote some code an i can ganerate md5 string,but i have problem first time i show you my code
public class MD5Hash
{
public static void main(String args[])
{
computeMD5Hash("dbox#service" + "2014-12-24T18:34:49");
}
public static void computeMD5Hash(String password)
{
try
{
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(password.getBytes("UTF-16"));
digest.update(password.getBytes());
byte messageDigest[] = digest.digest();
StringBuffer MD5Hash = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++)
{
String h = Integer.toHexString(0xFF & messageDigest[i]);
while (h.length() < 2)
h = "0" + h;
MD5Hash.append(h);
}
// result.setText("MD5 hash generated is: " + " " + MD5Hash);
System.out.println("MD5 hash generated is: " + " " + MD5Hash);
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
}
}
as i said i can recive md5 string but my friend is .net developer and he also wrote code and my md5 string is different .this is a his C# code
public static string CreateMD5(string plain)
{
MD5 md5 = MD5.Create();
byte[] inputBytes = Encoding.Unicode.GetBytes(plain);
byte[] hashBytes = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("x2"));
}
return sb.ToString();
}
somethink is a wrong in my Java code because i want my Md5 string to send server and when i send my md5 string to server i have error -my friend has not... what is a wrong in my code if anyone knows solution please help me thanks
Upvotes: 1
Views: 3304
Reputation: 17935
The difference between the programs is in the encoding used to convert the characters of the String into bytes.
UTF-16LE
Your friend's C# program is using Encoding.Unicode.GetBytes()
which defaults to UTF-16LE
and thus produces ea15fbcf2123906e6fcb9f2a3b243492
.
Your Java program is using String.getBytes()
which defaults to your current Locale's encoding (probably something like UTF-8
or Windows-1252
, but obviously something which is backwards compatible to US-ASCII-7
) and thus produces 70F00E5BD872BD73EC6A8B4B8C8C9FEF
.
You have to decide which encoding actually should be used. I'd say that for such use cases, using UTF-8
is most common and suggest that you both agree on UTF-8
. But no matter what, you need to agree on something.
UTF-8
or UTF-16LE
in JavaReplace the line
digest.update(password.getBytes());
with
digest.update(password.getBytes(StandardCharsets.UTF_16LE));
or
digest.update(password.getBytes(StandardCharsets.UTF_8));
You can also use charsets beyond those defined in StandardCharsets
. In that case you need to use the String
argument version of String.getBytes()
and deal with UnsupportedEncodingException
, like this:
try {
digest.update(password.getBytes("ISO-8859-15"));
} catch (final UnsupportedEncodingException e) {
throw new AssertionError(e);
}
main()
so it can be called with Md5Sum.main()
instead of Md5Sum.main(new String[0]);
when testing it.print
into return
.Formatter
for converting bytes to hex String
because it's far more convenient: It uses a StringBuilder
which is faster than a StringBuffer
, and it offers a format()
method which makes the conversion much simpler.final
because we intend to never reassign them.for
-loop with foreach
-loop because we don't use the index variable.MD5
to be available, and if it is not, it is an internal error of our program and abort. A crashed program causes less damage than a crippled one.public class Md5Sum {
public static void main(final String... args) {
final String md5sum = md5sum("dbox#service" + "2014-12-24T18:34:49");
System.out.println("MD5 hash generated is: " + md5sum);
}
public static String md5sum2(final String plaintext) {
try {
final Formatter formatter = new Formatter();
final MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(plaintext.getBytes(StandardCharsets.UTF_16LE));
for (final byte b : digest.digest())
formatter.format("%02x", b);
return formatter.toString();
} catch (final NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
}
}
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import static java.nio.charset.StandardCharsets.UTF_16LE;
public class Md5Sum {
public static void main(final String... args) {
final String md5sum = md5sum("dbox#service" + "2014-12-24T18:34:49");
System.out.println("MD5 hash generated is: " + md5sum);
}
public static String md5sum(final String plaintext) {
return toHexString(md5sum(plaintext.getBytes(UTF_16LE)));
}
private static byte[] md5sum(final byte... bytes) {
final MessageDigest digest = createMD5();
digest.update(bytes);
return digest.digest();
}
private static MessageDigest createMD5() {
try {
return MessageDigest.getInstance("MD5");
} catch (final NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
}
private static String toHexString(final byte... bytes) {
final Formatter formatter = new Formatter();
for (final byte b : bytes)
formatter.format("%02X", b);
return formatter.toString();
}
}
Upvotes: 2
Reputation: 106
On C# sample Encoding.Unicode gives you UTF-16 string to pass to digest, while on Java side UTF-8 string is passed to digest.
Upvotes: 1