java加密字节编码_java一些加密算法中为什么要将每个字节都&0xff?

本文探讨了Java加密算法中为何需要对字节进行`&0xff`操作,涉及位与运算和计算机基础知识。该操作用于确保在转换为十六进制字符串时,无论是正数还是负数,都能正确保留字节的低八位信息,防止高位符号位扩展带来的错误。通过举例说明了正数、负数在位运算中的变化,并解释了补码的概念。
摘要由CSDN通过智能技术生成

java的一些加密算法中,需要将字节数组的hash value转换成十六进制,代码如下:

public String getSHA2HexValue(String str) {

byte[] cipher_byte;

try{

MessageDigest md = MessageDigest.getInstance("SHA-256");

md.update(str.getBytes());

cipher_byte = md.digest();

StringBuilder sb = new StringBuilder(2 * cipher_byte.length);

for(byte b: cipher_byte) {

sb.append(String.format("%02x", b&0xff) );

}

return sb.toString();

} catch (Exception e) {

e.printStackTrace();

}

return "";

}

代码中要将每个字节都 & 0xff,为什么呢?这就涉及到计算机基础知识:

&是位与运算:

1 & 1 = 1

0 & 1 = 0

0 & 0 = 0

0xff是十六进制数(十进制为255),因为其是int类型,所以二进制表示

为:0000 0000 0000 0000 0000 0000 1111 1111

这样 a & 0xff 的意思就是取a的低八位。

例1:

byte b = 2;

int i = b & 0xff;

分析:

1、b的二进制为:0000 0010 ,要和int类型的0xff运算,首先要进行类型转换,将b转换成int类型,

2、int类型的2的二进制为:0000 0000 0000 0000 0000 0000 0000 0010

3、与0xff进行&运算,结果i为:0000 0000 0000 0000 0000 0000 0000 0010

发现结果仍然是2,没有变,那位啥还要 &0xff呢?这是因为虽然正数不变,可负数就不一样了,负数如果不&0xff 就会错。

注意:负数在计算机中是以补码的形式存在的,补码的计算方法如下:

1、原数取绝对值;

2、将其二进制按位取反(1变0,0变1)

3、加1

例2:

-2的补码计算:

1、2的绝对值:0000 0010

2、取反:1111 1101

3、加1:1111 1110

例3:

byte b = -2;

int i = b & 0xff;

分析:

1、b的二进制为:1111 1110

2、转换成int类型的-2,其二进制为:1111 1111 1111 1111 1111 1111 1111 1110

(原来是0xfe,现在变成了0xfffffffe,发生了符号补位,结果就不对了,所以需要将高位清除)

3、与0xff进行&运算,结果i为:0000 0000 0000 0000 0000 0000 1111 1110 (取了低8位,十六进制为fe)

补位扩展:

窄的整型转换成较宽的整型时符号扩展规则:如果最初的数值类型是有符号的,那么就执行符号扩展(即如果符号位

为1,则扩展为1,如果为零,则扩展为0);如果它是char,那么不管它将要被提升成什么类型,都执行零扩展。

byte是有符号的,所以进行符号位扩展,如例3中的-2,因为我们需要的是0扩展,所以进行&0xff消除高位。

char是没有符号的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值