There are some SO quetions but no helped me. I would like to convert byte[]
from org.apache.commons.codec.digest.HmacUtils
to String. This code produces some weird output:
final String value = "value";
final String key = "key";
byte[] bytes = HmacUtils.hmacSha1(key, value);
String s = new String(bytes);
What am I doing wrong?
-
1Generally, you display sha1 hashes in hex. Commons Codec has a hex encoder.Elliott Frisch– Elliott Frisch2015年09月26日 19:41:36 +00:00Commented Sep 26, 2015 at 19:41
-
Probably relevant, possibly duplicate: stackoverflow.com/questions/9655181/… The resulting 'random binary' of the hash function will otherwise not be a useful text/string value.user2864740– user28647402015年09月26日 19:53:45 +00:00Commented Sep 26, 2015 at 19:53
4 Answers 4
Try to use:
String st = HmacUtils.hmacSha1Hex(key, value);
Comments
For a more general solution, if you don't have HmacUtils available:
// Prepare a buffer for the string
StringBuilder builder = new StringBuilder(bytes.length*2);
// Iterate through all bytes in the array
for(byte b : bytes) {
// Convert them into a hex string
builder.append(String.format("%02x",b));
// builder.append(String.format("%02x",b).toUpperCase()); // for upper case characters
}
// Done
String s = builder.toString();
To explain your problem: You are using a hash function. So a hash is usually an array of bytes which should look quite random.
If you use new String(bytes) you try to create a string from these bytes. But Java will try to convert the bytes to characters.
For example: The byte 65 (hex 0x41) becomes the letter 'A'. 66 (hex 0x42) the letter 'B' and so on. Some numbers can't be converted into readable characters. Thats why you see strange characters like '�'.
So new String(new byte[]{0x41, 0x42, 0x43}) will become 'ABC'.
You want something else: You want each byte converted into a 2 digit hex String (and append these strings).
Greetings!
Comments
First, the result of hmacSha1
would produce a digest, not not a clear String
. Besides, you may have to specify an encoding format, for example
String s = new String(bytes, "US-ASCII");
or
String s = new String(bytes, "UTF-8");
2 Comments
You may need to have an encoding format. Check out this link here.