Two Laptop Bag*
The moose likes Java in General and the fly likes Printing the value of a byte as a hexstring Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Printing the value of a byte as a hexstring" Watch "Printing the value of a byte as a hexstring" New topic
Author

Printing the value of a byte as a hexstring

Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
I want to convert a byte[] array to a hexstring. I have no problem iterating through the array. However, the only way I have found to convert an integral data type to a hexstring is by using Integer.toHexString() or Integer.toString(int i, int radix). There are two problems I would like to address by using these methods:

1) Neither method pads with leading 0's. This isn't a big deal, but would be a nice feature.

2) More importantly, these both widen a byte to an int before converting it to a hexstring. This means that if the byte represents a negative number then the hexstring will 8 characters instead of just two because of all the leading 1's. This is highly undesireable.

I looked at java.text.NumberFormat briefly, but it doesn't seem to have any facilities to convert integral numbers to a given base. Am I missing something here or is this just a limitation of the Java API? If the later, what is a decent work-around to do what I want? I can easily write my own method to pad leading 0's. I could just call substring() on the result of toHexString() in order to get the last two characters, but this seems quite inelegant to me.

Any suggestions will be appreciated.

Layne


Java API Documentation
The Java Tutorial
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608


Lovely language isn't it?
[ September 18, 2005: Message edited by: Tony Morris ]

Tony Morris
Java Q&A (FAQ, Trivia)
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Thanks for the code. I like how your method uses the Iterable interface so that it isn't limited to just arrays. I understand how to iterate over the array. My question was primarily concerned with issues converting each individual byte.

The code above still doesn't solve the second problem. Say for example, one of the bytes in the array is -1. Integer.toHexString() will return "ffffff" instead of just "ff". (In fact, your solution will append "0ffffffff" since the hex.length() is not 1.) Similar issues will arise with any negative number which means the resulting String will have more than two characters for each byte. I guess I can just use substring() to get the last two bytes, but as I said earlier, that seems like an ugly solution to me. Maybe I'm just too paranoid about writing elegant code

Layne
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 687
    
    1
To use bytes as unsigned small ints, AND them with 0xFF after they have been promoted to an int to strip the h.o. sign bits.
To get leading 0's append digits to "0000000" and use substring to pickup rightmost n chars.
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Norm Radder:
To use bytes as unsigned small ints, AND them with 0xFF after they have been promoted to an int to strip the h.o. sign bits.
To get leading 0's append digits to "0000000" and use substring to pickup rightmost n chars.


I think you misunderstand my question. I am creating a String representation of each byte in an array. Integer.toHexString() returns a String with too many characters (8 instead of 2). I can't AND a String with 0xFF to remove the leading digit characters. I guess I can use substring() to obtain just the last two characters in the resulting String. Alternatively, I can write my own subroutine that takes a byte and doesn't use Integer.toHexString() at all. Hmm...that actually sounds much more appealing than trying to write a workaround.

Layne
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by Layne Lund:
Thanks for the code. I like how your method uses the Iterable interface so that it isn't limited to just arrays. I understand how to iterate over the array. My question was primarily concerned with issues converting each individual byte.

The code above still doesn't solve the second problem. Say for example, one of the bytes in the array is -1. Integer.toHexString() will return "ffffff" instead of just "ff". (In fact, your solution will append "0ffffffff" since the hex.length() is not 1.) Similar issues will arise with any negative number which means the resulting String will have more than two characters for each byte. I guess I can just use substring() to get the last two bytes, but as I said earlier, that seems like an ugly solution to me. Maybe I'm just too paranoid about writing elegant code

Layne



eh?



If this is not desired output, what is?
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061

If this is not desired output, what is?[/qb]<hr></blockquote>

Hmm...I that looks like the output I want. When I looked at the code earlier, I couldn't see anything that truncated the output to 2 characters or less. I guess it has something to do with this part:


If so, I don't understand why this works. I'll have to look at the bit representation to figure it out.

With that said, I think I would prefer to just do the conversion myself using modulus and division operations. It wouldn't be that difficult since the first digit is b / 16 and the second digit is b % 16 with the appropriate substitutions for 10 through 15, of course.

Layne
[ September 19, 2005: Message edited by: Layne Lund ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
JDK 5 does offer other alternatives too, such as:


"I'm not back." - Bill Harding, Twister
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 687
    
    1
> Integer.toHexString() returns a String with too many characters (8 instead
of 2

If a byte(being signed has its h.o. bit set when it is converted to an int, the sign will spread thru the h.o. bits of the int. Using toHexString() will then output 0xFFFFFFFF. I assume what you want to see is 0XFF
To treat a byte as unsigned, ie prevent the spread of 1 bits, AND it with 0xFF.
Output is: fa
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Jim Yingst:
JDK 5 does offer other alternatives too, such as:



Thanks. I am still learning about all the things that are available in Java 5. I forgot about the nice little printf-like features. Perhaps I will use this.

Layne
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Norm Radder:
> Integer.toHexString() returns a String with too many characters (8 instead
of 2

If a byte(being signed has its h.o. bit set when it is converted to an int, the sign will spread thru the h.o. bits of the int. Using toHexString() will then output 0xFFFFFFFF. I assume what you want to see is 0XFF
To treat a byte as unsigned, ie prevent the spread of 1 bits, AND it with 0xFF.
Output is: fa


Thank you for clarifying. I misunderstood what you meant in your original suggestion. The code snippet makes it much more clear.

Thanks,

Layne
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Printing the value of a byte as a hexstring