为什么 & 0xff 应用于字节变量
Why is & 0xff applied to a byte variable
为什么在基于时间的 OTP(TOTP,RFC 6238)的参考实现中将 & 0xff
应用于字节变量?在我看来,这不会改变值,因为字节数据类型的长度为 8 位。
byte[] hash = hmac_sha(crypto, k, msg);
int offset = hash[hash.length - 1] & 0xf;
int binary =
((hash[offset] & 0x7f) << 24) |
((hash[offset + 1] & 0xff) << 16) |
((hash[offset + 2] & 0xff) << 8) |
(hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[codeDigits];
此外,将XAND
运算符应用于第一个带有0x7f
的元素的原因是什么?它仍然可以得到一个 10 位数字,比 DIGITS_POWER
中最大的条目 100 000 000
.
大
(https://www.rfc-editor.org/rfc/rfc6238, 第 13 页)
根据 JLS,文字 0xff
的类型为 int
。
同样根据 JLS,当在 byte
和 int
之间执行操作时,byte
安全地 加宽 为 int
结果是 int
.
这意味着表达式:
hash[offset + 1] & 0xff
大致相同:
(int)(hash[offset + 1]) & 0xff
事实上,需要一个 int
作为结果类型才能使以下移位操作有意义。
(hash[offset + 1] & 0xff) << 16
如果位移是在 byte
上完成的,这些位将旋转回原来的位置(16 是 8 的整数倍)。
整个代码正在从 byte[]
.
构造 int
用在高字节上的奇数掩码 0x7f
代替 0xff
来掩码最左边(或最高有效位)的位,即 符号bit,保证最后的结果不为负。
byte b = -5;
System.out.println(b);
System.out.println(b & 0xFF);
这会产生以下输出:
-5
251
当执行&
时,两个操作数首先被提升为32位。 -5
表示为 11111111111111111111111111111011
,而 0xFF
只是“末尾有 24 个零和 8 个一”,因此 (-5) & 0xFF
给出 11111011
(省略前导零) .
操作确实改变了值。 byte & 0xff
将带符号的字节转换为表示对应于字节位模式的无符号值的 int。
为什么在基于时间的 OTP(TOTP,RFC 6238)的参考实现中将 & 0xff
应用于字节变量?在我看来,这不会改变值,因为字节数据类型的长度为 8 位。
byte[] hash = hmac_sha(crypto, k, msg);
int offset = hash[hash.length - 1] & 0xf;
int binary =
((hash[offset] & 0x7f) << 24) |
((hash[offset + 1] & 0xff) << 16) |
((hash[offset + 2] & 0xff) << 8) |
(hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[codeDigits];
此外,将XAND
运算符应用于第一个带有0x7f
的元素的原因是什么?它仍然可以得到一个 10 位数字,比 DIGITS_POWER
中最大的条目 100 000 000
.
(https://www.rfc-editor.org/rfc/rfc6238, 第 13 页)
根据 JLS,文字 0xff
的类型为 int
。
同样根据 JLS,当在 byte
和 int
之间执行操作时,byte
安全地 加宽 为 int
结果是 int
.
这意味着表达式:
hash[offset + 1] & 0xff
大致相同:
(int)(hash[offset + 1]) & 0xff
事实上,需要一个 int
作为结果类型才能使以下移位操作有意义。
(hash[offset + 1] & 0xff) << 16
如果位移是在 byte
上完成的,这些位将旋转回原来的位置(16 是 8 的整数倍)。
整个代码正在从 byte[]
.
int
用在高字节上的奇数掩码 0x7f
代替 0xff
来掩码最左边(或最高有效位)的位,即 符号bit,保证最后的结果不为负。
byte b = -5;
System.out.println(b);
System.out.println(b & 0xFF);
这会产生以下输出:
-5
251
当执行&
时,两个操作数首先被提升为32位。 -5
表示为 11111111111111111111111111111011
,而 0xFF
只是“末尾有 24 个零和 8 个一”,因此 (-5) & 0xFF
给出 11111011
(省略前导零) .
操作确实改变了值。 byte & 0xff
将带符号的字节转换为表示对应于字节位模式的无符号值的 int。