Java 位旋转:编码无符号原语
下面是一个类,它将无符号基本类型编码为字节数组,并将编码的字节数组返回为十进制字符串。我从概念上理解Java 位旋转:编码无符号原语,java,bit-manipulation,Java,Bit Manipulation,下面是一个类,它将无符号基本类型编码为字节数组,并将编码的字节数组返回为十进制字符串。我从概念上理解encodeIntBigEndian和byteArrayToDecimalString的工作原理。但是,我希望澄清以下内容: 为什么/如何将val移位((size-i-1)*Byte.size)会产生一个无符号的java字节值 另外,为什么应用0xff的字节掩码会将字节转换为十进制字符串值 公共类BruteForceCoding{ 私有静态字节byteVal=101;//111 私有静态short
encodeIntBigEndian
和byteArrayToDecimalString
的工作原理。但是,我希望澄清以下内容:
val
移位((size-i-1)*Byte.size)
会产生一个无符号的java字节值0xff
的字节掩码会将字节转换为十进制字符串值公共类BruteForceCoding{
私有静态字节byteVal=101;//111
私有静态shortVal=10001;//一万零一
私有静态int intVal=100000000001;//一亿零一
私有静态longVal=10000000001L;//1万亿和1万亿
私有最终静态int BSIZE=Byte.SIZE/Byte.SIZE;
private final static int SSIZE=Short.SIZE/Byte.SIZE;
私有最终静态int-ISIZE=Integer.SIZE/Byte.SIZE;
私有最终静态int LSIZE=Long.SIZE/Byte.SIZE;
私有最终静态int BYTEMASK=0xFF;//8位
公共静态字符串byteArrayToDecimalString(字节[]bArray){
StringBuilder rtn=新的StringBuilder();
for(字节b:bArray){
附加(b&BYTEMASK)。附加(“”);
}
返回rtn.toString();
}
公共静态int encodeIntBigEndian(字节[]dst,长val,int偏移量,int大小){
对于(int i=0;i>((size-i-1)*byte.size));
}
返回偏移量;
}
公共静态void main(字符串[]args){
字节[]消息=新字节[BSIZE+SSIZE+ISIZE+LSIZE];
//对目标字节数组中的字段进行编码
int offset=encodeIntBigEndian(消息,字节,0,BSIZE);
偏移量=encodeIntBigEndian(消息、短值、偏移量、SSIZE);
偏移量=encodeIntBigEndian(消息、intVal、偏移量、ISIZE);
encodeIntBigEndian(消息、长值、偏移量、LSIZE);
System.out.println(“编码消息:+byteArrayToDecimalString(消息));
}
}
1)它本身并没有。它所做的是将值向下移动一个字节的单位。但是,当与丢弃高位的转换为(byte)
组合时,这相当于移位和掩码操作,从值中提取单个字节
2) 没有。它屏蔽高位,保留值的低位八位(一个字节)——与前一种情况下执行的转换为byte
的操作相同。但是,默认情况下,将字节呈现为字符串会生成一个包含表示其二进制值(从0到255)的十进制数的字符串,并且在调用.append()时会隐式发生这种情况
为什么/如何将val移位((size-i-1)*Byte.size)
会产生一个无符号的java字节值
没有>
是一个,因此它不会更改其左参数的符号<按非零位数编码>>>可以保证产生非负结果,因此可以认为具有无符号输出
无论哪种方式,只要将其转换为字节
,该值就会再次签名,因为Java没有无符号字节类型
此外,为什么应用0xff字节掩码会将字节转换为十进制字符串值
没有
十进制转换发生在
(b&BYTEMASK)
的类型为int
,其值在[0,256]范围内,StringBuilder.append(int)
作为其参数的十进制表示形式的追加
更新: 了解
因此,给定int
0x01234567
它将按顺序将字节0x01 0x23 0x45 0x67
放入dst
中。因此,如果我理解,应用0xFF
或11111111
字节任务清除高位——本质上是在转换为t的十进制字符串表示时,对隐式应用的符号求反二进制值?是的。例如,0xFFFE(除最低位外的所有1)是-2的2的补码表示形式。将其与0xFF按位相加将产生0x00FE,即254的2的补码表示形式。高位是2的补码整数中的符号位这一事实对于位旋转没有意义。encodeIntBigEndian
应该模拟通过tearrayoutPutstream写入>.我知道该方法将值向右移动一个字节,然后清除较高的位,但这样做在将值编码为字节方面有什么作用?
public class BruteForceCoding {
private static byte byteVal = 101; // one hundred and one
private static short shortVal = 10001; // ten thousand and one
private static int intVal = 100000001; // one hundred million and one
private static long longVal = 1000000000001L;// one trillion and one
private final static int BSIZE = Byte.SIZE / Byte.SIZE;
private final static int SSIZE = Short.SIZE / Byte.SIZE;
private final static int ISIZE = Integer.SIZE / Byte.SIZE;
private final static int LSIZE = Long.SIZE / Byte.SIZE;
private final static int BYTEMASK = 0xFF; // 8 bits
public static String byteArrayToDecimalString(byte[] bArray) {
StringBuilder rtn = new StringBuilder();
for (byte b : bArray) {
rtn.append(b & BYTEMASK).append(" ");
}
return rtn.toString();
}
public static int encodeIntBigEndian(byte[] dst, long val, int offset, int size) {
for (int i = 0; i < size; i++) {
dst[offset++] = (byte) (val >> ((size - i - 1) * Byte.SIZE));
}
return offset;
}
public static void main(String[] args) {
byte[] message = new byte[BSIZE + SSIZE + ISIZE + LSIZE];
// Encode the fields in the target byte array
int offset = encodeIntBigEndian(message, byteVal, 0, BSIZE);
offset = encodeIntBigEndian(message, shortVal, offset, SSIZE);
offset = encodeIntBigEndian(message, intVal, offset, ISIZE);
encodeIntBigEndian(message, longVal, offset, LSIZE);
System.out.println("Encoded message: " + byteArrayToDecimalString(message));
}
}
rtn.append(b & BYTEMASK).append(" ")
for (int i = 0; i < size; i++) {
dst[offset++] = (byte) (val >> ((size - i - 1) * Byte.SIZE));
}
dst[offset ] = (byte) (val >> 24); // (byte) 0x??????01 == 0x01
dst[offset+1] = (byte) (val >> 16); // (byte) 0x????0123 == 0x23
dst[offset+2] = (byte) (val >> 8); // (byte) 0x??012345 == 0x45
dst[offset+3] = (byte) (val >> 0); // (byte) 0x01234567 == 0x67