import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class JavaMD5 {
public static void main(String[] args) {
String passwordToHash = "MyPassword123";
String generatedPassword = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(passwordToHash.getBytes());
byte[] bytes = md.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
generatedPassword = sb.toString();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(generatedPassword);
}
}
This line is the problem :
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
what does each part do in this structure????
Thanks and I'm sorry for asking Beacuse I'm new in java.
Presumably most of the code is clear and the only mystery for you here is this expression:
(bytes[i] & 0xff) + 0x100
The first part:
bytes[i] & 0xff
widens the byte at position i to an int value with zeros in bit positions 8-31. In Java, the byte data type is a signed integer value, so the widening sign-extends the value. Without the & 0xff, values greater than 0x7f would end up as negative int values. The rest is then fairly obvious: it adds 0x100, which simply turns on the bit at index 8 (since it is guaranteed to be 0 in (bytes[i] & 0xff). It is then converted to a hex String value by the call to Integer.toString(..., 16).
The reason for first adding 0x100 and then stripping off the 1 (done by the substring(1) call, which takes the substring starting at position 1 through the end) is to guarantee two hex digits in the end result. Otherwise, byte values below 0x10 would end up as one-character strings when converted to hex.
It's debatable whether all that has better performance (it certainly isn't clearer) than:
sb.append(String.format("%02x", bytes[i]));
It's a really messy way of translating to a hexadecimal string.
& 0xFF performs a binary AND, causing the returning value to be between 0 and 255 (which a byte always is anyway)+ 0x100 adds 256 to the result to ensure the result is always 3 digitsInteger.toString(src, 16) converts the integer to a string with helix 16 (hexadecimal).substring(1) strips the first character (the 1 from step 2)So, this is a very elaborate and obfuscated way to convert a byte to an always 2-character hexadecimal string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With