• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Printing the value of a byte as a hexstring

 
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Lovely language isn't it?
[ September 18, 2005: Message edited by: Tony Morris ]
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Rancher
Posts: 5008
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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 ]
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
JDK 5 does offer other alternatives too, such as:
 
Norm Radder
Rancher
Posts: 5008
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
> 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
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Grow a forest with seedballs and this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic