Binary input to Hexadecimal conversion

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

kalyangkmAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ozoCommented:
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.
0
Slick812Commented:
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] );
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
kalyangkmAuthor Commented:
Could you please elaborate explaining each statement of the for loop.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

kalyangkmAuthor Commented:
Thanks Slick812. Let me analyze and get back to you.
0
Slick812Commented:
I need to go for tonight, will look at this tomorrow
0
kalyangkmAuthor 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 "
0
dpearsonCommented:
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?
0
Slick812Commented:
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
0
kalyangkmAuthor Commented:
Thank You Slick812
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.