在使用md5加密的时候,hash数组转字符串的方法里面,有一段的代码上面写了 0xff,一开始优点不太懂,后面上网补了一下基础,记录下了;
代码示例:
public static String byteToHexString(byte[] b) { StringBuffer hexString = new StringBuffer(); for (int i = 0; i < b.length; i++) { String hex = Integer.toHexString(b[i] & 0xFF); //就是这一段代码 if (hex.length() == 1) { hex = '0' + hex; } hexString.append(hex.toUpperCase()); } return hexString.toString(); }
故事,要从计算机的基础开始:
原码:原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。
反码:数值的正负相关;
正数的反码还是等于原码,例如:十进制数100D,它的二进制数是0B1100100(0B 0000 0000 0000 0000 0000 0000 0110 0100,整数类型4字节共32位,需要在前面补0);
负数的反码就是他的原码除符号位外,按位取反。例如:十进制数-100D,它的二进制数是0B 1000 0000 0000 0000 0000 0000 0110 0100;那么反码是:0B 1111 1111 1111 1111 1111 1111 1001 1011
补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
例如负数-1,原码是1,补码是0b1111 1111
下面是用代码来去对应的进制值:
1 public class Test { 2 public static void main(String[] args) { 3 int num = 100; 4 int num2= -100; 5 System.out.println(Integer.toBinaryString(num)); 6 //1100100 正数,输出为原码 7 System.out.println(Integer.toBinaryString(num2)); 8 //11111111111111111111111110011100 负数,输出为反码 9 } 10 }
说完这些:
通过加密算法或者其他方法获取到的byte数组,其中的数值的取值范围是[-128 , 127 ] (Byte.MIN_VALUE=-128 ,Byte.MAX_VALUE=127),所以有可能为正数或者负数;执行Integer.toBinaryString(num)这段代码的时候,会先进行类型提升的操作,就是byte提升到int(坑爹,原来这个方法是int,执行需要把两个值转成int);何为补位?就是btye占用一个字节共八位,int占用4个字节共32位,进行&操作,需要转成二进制数,正数直接在前面补24个0,负数需要在二进制数上面补24个1;byte类型数值执行 & 0xff 操作的时候,正数不会改变本身的值,0xff是16进制数,这个刚好8位都是1的二进制数,而且转成int类型的时候,高位会补0;在&正数byte值的话,对数值不会有改变,toBinaryString保持2位十六进制数,在&负数数byte值的话,对数值前面补位的1会变成0,toBinaryString保持2位十六进制数,也不会有前面的ffffff
希望以后自己回来看能看懂吧