将字符串转换为 HexString 时低半字节和高半字节的目的是什么
What is the purpose of low and high nibble when converting a string to a HexString
最近,我通过一些 MD5 示例开始了解安全性,虽然 MD5 不再安全,但大部分情况下理解起来相当简单,这是一个很好的起点。尽管如此,在将字符串转换为十六进制字符串时,我还是有一个关于高半字节和低半字节的问题。
所以我知道高半字节和低半字节等于半个字节,也可以是代表单个十六进制数字的十六进制数字。我不明白的是它们究竟是如何工作的以及它们服务的目的。我一直在 google 上搜索,但找不到太多有助于解释他们在他们所处的上下文中所做的事情的答案。这是转换的上下文:
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 );
}
我不太明白 for 语句中发生了什么。我将不胜感激任何帮助理解这一点,如果在某些地方有一些 link 我可以了解更多这方面的信息,请也留下它。
我了解半字节的基本定义,但不了解操作以及对数字 4 的赋值是做什么的。
如果我需要 post 完整的示例代码,我会询问,因为我不确定是否需要它。
只是位运算。 & 字符获取每个的字面值并对它们执行逻辑与操作。
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' 为字符串的十六进制为 24 的那部分提供“18”。
此代码只是将字节数组转换为十六进制表示形式。在 for
循环中,每个字节被转换成两个字符。我认为通过示例更容易理解。
假设数组中的一个字节是 218
(无符号)。那是二进制的1101 1010
。
lo4
通过将字节与位掩码 00001111
:
进行与运算来获取最低的 4 位
int lo4 = b & 0x0F;
这导致 1010
、10
(十进制)。
hi4
通过与位掩码 1111 0000
进行与运算并向右移动 4 位来获得最高的 4 位:
int hi4 = ( b & 0xF0 ) >> 4;
这会导致 1101
、13
(十进制)。
现在要得到这个字节的十六进制表示,你只需要将10
和13
转换成它们的十六进制表示并连接起来。为此,您只需在特定索引处查找准备好的 HEX_CHARS
字符串中的字符。 10
-> A
,13
-> D
,导致 218
-> DA
。
最近,我通过一些 MD5 示例开始了解安全性,虽然 MD5 不再安全,但大部分情况下理解起来相当简单,这是一个很好的起点。尽管如此,在将字符串转换为十六进制字符串时,我还是有一个关于高半字节和低半字节的问题。
所以我知道高半字节和低半字节等于半个字节,也可以是代表单个十六进制数字的十六进制数字。我不明白的是它们究竟是如何工作的以及它们服务的目的。我一直在 google 上搜索,但找不到太多有助于解释他们在他们所处的上下文中所做的事情的答案。这是转换的上下文:
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 );
}
我不太明白 for 语句中发生了什么。我将不胜感激任何帮助理解这一点,如果在某些地方有一些 link 我可以了解更多这方面的信息,请也留下它。
我了解半字节的基本定义,但不了解操作以及对数字 4 的赋值是做什么的。
如果我需要 post 完整的示例代码,我会询问,因为我不确定是否需要它。
只是位运算。 & 字符获取每个的字面值并对它们执行逻辑与操作。
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' 为字符串的十六进制为 24 的那部分提供“18”。
此代码只是将字节数组转换为十六进制表示形式。在 for
循环中,每个字节被转换成两个字符。我认为通过示例更容易理解。
假设数组中的一个字节是 218
(无符号)。那是二进制的1101 1010
。
lo4
通过将字节与位掩码 00001111
:
int lo4 = b & 0x0F;
这导致 1010
、10
(十进制)。
hi4
通过与位掩码 1111 0000
进行与运算并向右移动 4 位来获得最高的 4 位:
int hi4 = ( b & 0xF0 ) >> 4;
这会导致 1101
、13
(十进制)。
现在要得到这个字节的十六进制表示,你只需要将10
和13
转换成它们的十六进制表示并连接起来。为此,您只需在特定索引处查找准备好的 HEX_CHARS
字符串中的字符。 10
-> A
,13
-> D
,导致 218
-> DA
。