-1

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.

4

2 回答 2

2

此代码只是将字节数组转换为十六进制表示。在for-loop 中,每个字节都被转换为两个字符。我认为通过一个例子更容易理解它。

假设您的数组中的一个字节是218(无符号)。那是1101 1010二进制的。

lo4通过与位掩码对字节进行与运算来获得最低 4 位00001111

int lo4 = b & 0x0F;

这导致1010,10十进制。

hi4通过与位掩码进行 AND 运算1111 0000并向右移动 4 位来获得最高 4 位:

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

这导致1101,13十进制。

现在要获得这个字节的十六进制表示,您只需要将其转换为十六进制表示1013连接。为此,您只需HEX_CHARS在特定索引处查找准备好的字符串中的字符。10-> A13-> D,导致218-> DA

于 2018-05-04T20:53:38.247 回答
1

这只是位操作。& 字符获取每个字符的字面值,并对它们进行逻辑与。

int lo4 = b & 0x0F;

例如如果 b = 24 那么它将评估为

 00011000
+00001111
=00001000

第二条这样的行对前四位执行相同的操作。

 00011000
+11110000
=00010000

'>>' 将所有位在该方向上移动一定数量,因此

00010000 >> 4 = 00000001. 

这样做是为了让您可以从数字中导出十六进制值。由于十六进制中的每个字符可以通过将数字拆分为 4 位来表示 4 位,因此我们可以对其进行转换。

在 b = 24 的情况下,我们没有 lo4 = 1000 或 8 和 hi4 = 0001 或 1。循环的最后一部分为每个分配字符值。

Hex_chars[hi4] = '1' 和 Hex_chars[lo4] = '8' 这为字符串的那部分给出“18”,即十六进制的 24。

于 2018-05-04T20:51:24.943 回答