所以我理解如何更改一个字节内的单个位,我不确定为什么我的特定代码无效。
public static void setBit(byte[] input, int position, int value) {
int byteLocation = position / 8;
int bitLocation = position % 8;
byte tempByte = input[byteLocation];
if (value == 0)
tempByte = (byte) (tempByte & ~(1 << bitLocation));
else
tempByte = (byte) (tempByte | (1 << bitLocation));
input[byteLocation] = tempByte;
}
现在我用字符串“Testing1”(64位长)测试它,然后尝试设置位并显示值。它最多可以处理46位,然后在第47位,如果我尝试将其设置为1,它会自动运行,但是可以正常工作。
无法以我的方式看到错误,这是我测试它的方式
String test = "Testing1";
byte[] bytes = test.getBytes();
for (int i = 0; i < bytes.length; i++)
System.out.print(String.format("%8s", Integer.toBinaryString(bytes[i])).replace(' ', '0') + "[" + i + "] ");
setBit(bytes, 44, 1);
System.out.println();
for (int i = 0; i < bytes.length; i++)
System.out.print(String.format("%8s", Integer.toBinaryString(bytes[i])).replace(' ', '0') + "[" + i + "] ");
以下是我尝试将第47位更改为1
时的输出01010100[0] 01100101[1] 01110011[2] 01110100[3] 01101001[4] 01101110[5] 01100111[6] 00110001[7]
01010100[0] 01100101[1] 01110011[2] 01110100[3] 01101001[4] 11111111111111111111111111101110[5] 01100111[6] 00110001[7]
答案 0 :(得分:3)
将格式更改为
Integer.toBinaryString(0xFF & bytes[i])
需要屏蔽字节,因为它是符号扩展的,而不是零扩展的,为32位int
答案 1 :(得分:2)
问题是您在相关字节中设置符号位。所以,该字节现在具有负值。你调用Integer.toBinaryString()
,它接受一个int作为它的参数,而不是一个字节。字节被提升为int,并且它正确地计算值:
11101110
到它的等价整数:
11111111111111111111111111101110
答案 2 :(得分:0)
我使用^
(xor)
public static void setBit(byte[] input, int position, int value) {
int byteLocation = position / 8;
int bitLocation = position % 8;
input[byteLocation] = (byte) (input[byteLocation] ^ (byte) (1 << bitLocation));
}
答案 3 :(得分:0)
我没有太详细地看过它,但我认为一口咬的问题是它被扩展为一个int(因为它已经签名,1扩展为负int)。
只需取字符串的最后8个字符即可。
答案 4 :(得分:0)
我最近不得不这样做。
我设法通过(大量使用白板但是......)将原始位移到我想要替换的LSB的位置并使所有位包含我想要替换的MSB,1&#39;秒。
然后我想要我想要的位代替我要替换的位,向左移动我向右移动的相同数字,或者用原始移动结果,用XOR&#编辑&#39; 39;替换的面具。 (深吸一口气,我试着解释)
让我们说我有字节:
1111 1010 0001 1001
我想用0001替换半字节1010以产生:
1111 0001 0001 1001.
我为实现这一目标而进行的操作是:
1)向右移动8以产生:
0000 0000 1111 1010
2)OR掩码0xf(1111)产生:
0000 0000 1111 1111
3)用0000 0000 1111 1111替换0001以产生:
0000 0000 0000 0001
4)向左移动8以产生:
0000 0001 0000 0000
5)将掩码移动到LSB位置,将XOR移动到全字节
1111 1111 1111 1111
0000 1111 0000 0000
==================
1111 0000 1111 1111
6)和XOR&#39; ed,移动掩模与原件产生:
1111 0000 0001 1001
1111 0000 1111 1111
==================
1111 0000 0001 1001
7)或以上更换的结果:
1111 0000 0001 1001
0000 0001 0000 0000
==================
1111 0001 0001 1001&lt;&lt; 最终结果
==================
在java中,这导致函数:
public long overwriteBits(long overwrite, long with, long shift, long mask)
{
return ((((overwrite >> shift) | mask) & with) << shift) | (overwrite & (~0 ^ (mask << shift)));
}
在哪里&#34;覆盖&#34;是原始数据,&#34;&#34;是你想要的位代替位置&#34; shift&#34;和掩码是一系列正位,具有相同的替换长度。
为了做到这一点,我打电话(在sudo中):
overwriteBits(1111 1010 00011001, 0001 ,8,1111)
我想提一下,上面的内容适用于替换任何原语中的位,不需要字节数组。例如更换11位,如下所示:
1101001010101101 1111 0101 101 001101
1010 1010 101
overwriteBits(1101001010101101 1111 0101 101 001101 , 1010 1010 101, 6 , 11111111111)
/>
1101001010101101 1111 0101 101 001101
1101001010101101 1010 1010 101 001101
overwriteBits(1789785421l,1365l,6,0x7FF)