We help IT Professionals succeed at work.

Binary input to Hexadecimal conversion

kalyangkm
kalyangkm asked
on
I have this piece of code which is a code snippet from another code.  Could anyone explain how the bytes and hex characters are correlated and what exactly is being done with the string buffers on bytes and hex characters?

 private static final char[] HexChars = {  
    '0', '1', '2', '3', '4', '5', '6', '7',  
    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'  
    };  
    public static final String toHexString(byte[] bytes)   
    {  
        StringBuffer sb = new StringBuffer();  
        int i;  
        for (i=0; i < bytes.length; i++)       
        {  
            sb.append( HexChars[( bytes[i] & 0xf0 ) >>> 4] );  
            sb.append( HexChars[bytes[i] & 0x0f] );  
            //sb.append(HexChars[(bytes[i] >> 4) & 0xf]);  
            //sb.append(HexChars[bytes[i] & 0xf]);  
        }  
        return sb.toString();  
    }  

Open in new window

Comment
Watch Question

ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
There are two hex characters in a byte, and the high and low 4 bits in the bytes buffer are being translated into the string buffer.
OK, I'll try and give some definition for the "BIT" structure of a Byte in the bytes[ ] array used in code.
A Byte has 8 Bits, with 256 possible values, from Zero to Two Hundred and Fifty Five. However for Hexadecimal character output each Byte representation, uses Two characters, such as "e3" which would be 227 in decimal notation. So the Byte to Hex problem becomes, how to divide the 8bit Byte into two 4bit sections. You do this by using the BINARY "AND" operation which in Java uses the & operator, , when the & operation happens, ONLY the BITS MATCH in BOTH operators are passed to the result , so
in your code it is-
    bytes[j] & 0xf0
the HEX notation of 0xf0 (240) is the TOP 4 BITS - bits 128, 64, 32, and 16, and the result of & filter out all of the lower 4 bits. BUT the value is above 15 the max for the HexChars[] array, SO you now have to position shift to the right, the Top four bits down to the bottom 4 bits using the exacting right shift operator of Java as  >>>  ,  , so it looks like =
     ( bytes[j] & 0xf0 ) >>> 4
for the upper 4 bits. for the lower f bits you do "AND" operation with 15 ( 0xf HEX), but you do not need to shift any bits, since the HexChars[] array goes from 0 to 15.

do you need to add TWO text string characters for each byte as -
         sb.append( HexChars[( bytes[j] & 0xf0 ) >>> 4] );  
        sb.append( HexChars[bytes[j] & 0x0f] );

Author

Commented:
Could you please elaborate explaining each statement of the for loop.

Author

Commented:
Thanks Slick812. Let me analyze and get back to you.
I need to go for tonight, will look at this tomorrow

Author

Commented:
Slick812,

I am not sure I understand the following part, what are we achieving here by matching the BITS MATCH and further I am not sure why the position shift. I think once I understand how the 2 4bit sections are divided I would probably understand the rest. Could you please elaborate a bit more.

"when the & operation happens, ONLY the BITS MATCH in BOTH operators are passed to the result , so
in your code it is-
    bytes[j] & 0xf0
the HEX notation of 0xf0 (240) is the TOP 4 BITS - bits 128, 64, 32, and 16, and the result of & filter out all of the lower 4 bits. BUT the value is above 15 the max for the HexChars[] array, SO you now have to position shift to the right, the Top four bits down to the bottom 4 bits using the exacting right shift operator of Java as  >>>  ,  , so it looks like =
     ( bytes[j] & 0xf0 ) >>> 4 "
A byte (8-bits) represented in hex is 2 characters: XY where each character is 0-F (0-15).
So each character represents 4-bits in the byte.

( bytes[j] & 0xf0 ) >>> 4 extracts the first 4-bits and then HexChars(x) converts that to a character so you get 0-F.
( bytes[j] & 0x0f) extracts the second 4-bits and then HexChars(y) converts that to a character so you get another 0-F.

Put the two together and you're converting from bytes[j] to XY where each of X,Y is a hex character (0-F).

Makes sense?
OK, if you have NO experience in dealing with the ideas and concepts of the 'only binary' (just ON or Off, 0 or 1) "Bits" in a "Byte", then you will not see what the binary operations like "AND" , "OR", "XOR" , do or why they can be useful. Here is the BIT decimal equivalent values for each of 8 bits in byte.
128-64-32-16-8-4-2-1

(a NOTE about JAVA Bytes, due to trying to make Java, an easier language to learn-use, Bytes are NOT unsigned as in a value from 0 to 255, Java bytes are signed, and can have a decimal value from a negative -127 to positive 127. . . However operations Like & |  , and any shift operation are NOT affected by any way the JAVA interprets the bit values)

a Byte with the decimal value of 7 has these BITS set (bit set means it is NOT Zero, but One) -
0-0-0-0-0-1-1-1

a Byte with the decimal value of 80 is -
0-1-0-1-0-0-0-0

Please keep in mind that in the CPU mechanics computing, there is NO such thing (definition) as Decimal, Binary, HEX or Character(string), there is Only BITS, that can be On or Off.

The operation of "AND" does a Bit by Bit comparison for all Bits in two operator values, , , IF the test of the third position bit in each value are both set (value of 1) then that third bit value is set in the result value output.
if you have these two byte values in an "AND" operation-
0-0-0-0-0-1-0-0
0-0-0-0-1-0-0-0
the result is ZERO, no bits set, NO match of any corresponding bits.

if you have these two byte values in an "AND" operation-
0-0-0-0-0-1-1-0
0-0-0-0-1-0-1-0
the result is decimal 2, second bit is set, as both values have the second bit set.

       bit Shift
if you have a byte as decimal value 8 -
0-0-0-0-1-0-0-0

and do a right shift ONE place
      bytes[0] >> 1
the output result is
0-0-0-0-0-1-0-0
as decimal value 4, ALL bits, set and un set have been moved to the right One spot

Author

Commented:
Thank You Slick812