简体   繁体   中英

What is the purpose of low and high nibble when converting a string to a HexString

Recently I have been going through some examples of MD5 to start getting an understanding of security and MD5 has been fairly simple to understand for the most part and a good starting point even though it is no longer secure. Despite this I have a question regarding high and lo nibbles when it comes to converting a string to a hex string.

So I know high and low nibbles are equal to half a byte or also can be hex digits that represent a single hexadecimal digit. What I am not understanding though is exactly how they work and the purpose that they serve. I have been searching on google and I can't find much of an answer that will help explain what they do in the context that they are in. Here is the context of the conversion:

private static String toHexString( byte[] byteArray )
    {
        final String HEX_CHARS = "0123456789ABCDEF"; 

        byte[] result = new byte[byteArray.length << 1];
        int len = byteArray.length;
        for( int i = 0 ; i < len ; i++ )
        {
            byte b = byteArray[i]
            int lo4 = b & 0x0F;
            int hi4 = ( b & 0xF0 ) >> 4;


            result[i * 2] = (byte)HEX_CHARS.charAt( hi4 );
            result[i * 2 + 1] = (byte)HEX_CHARS.charAt( lo4 );
        }
        return new String( result );
    } 

I don't exactly understand what is going on in the for statement. I would appreciate any help understanding this and if there is some link to some places that I can learn more about this please also leave it.

I understand the base definition of nibble but not the operations and what the assignment to the number 4 is doing either.

If I need to post the full example code I will just ask as I am unsure if it is needed.

It's just bit operations. The & character takes the literal bit value of each and does a logical and on them.

int lo4 = b & 0x0F;

for instance if b = 24 then it will evaluate to this

 00011000
+00001111
=00001000

The second such line does the same on the first four bits.

 00011000
+11110000
=00010000

the '>>' shifts all of the bits a certain number in that direction so

00010000 >> 4 = 00000001. 

This is done so that you can derive the hex value from the number. Since each character in hex can represent 4 bits by splitting the number into pieces of 4 bits we can convert it.

in the case of b = 24 we no have lo4 = 1000 or 8 and hi4 = 0001 or 1. The last part of the loop assigns the character value for each.

Hex_chars[hi4] = '1' and Hex_chars[lo4] = '8' which gives you "18" for that part of the string which is 24 in hex.

This code simply converts a byte array to hexadecimal representation. Within the for -loop, each byte is converted into two characters. I think it's easier to understand it on an example.

Assume one of the bytes in your array is, say, 218 (unsigned). That's 1101 1010 in binary.

lo4 gets the lowest 4 bits by AND-ing the byte with the bitmask 00001111 :

int lo4 = b & 0x0F;

This results in 1010 , 10 in decimal.

hi4 gets the highest 4 bits by AND-ing with the bitmask 1111 0000 and shifting 4 bits to the right:

int hi4 = ( b & 0xF0 ) >> 4;

This results in 1101 , 13 in decimal.

Now to get the hexadecimal representation of this byte you only need to convert 10 and 13 to their hexadecimal representations and concatenate. For this you simply look up the character in the prepared HEX_CHARS string at the specific index. 10 -> A , 13 -> D , resulting in 218 -> DA .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM