我有一个字节数组myByteArray[82]
我想将此数组中的 37 位恰好更改为补码值。IE。如果 bit0 有一个“1”,我想将其更改为“0”。我需要更改前 37 个这样的位以在此字节数组中引入错误。
请建议如何做到这一点
尝试
byte[] a82 = ...
Set<Integer> set = new HashSet<Integer>();
while (set.size() < 37) {
set.add((int) (Math.random() * 82));
}
for (int i : set) {
int ibyte = i / 8;
int ibit = i % 8;
int m = 1 << ibit;
a[ibyte] ^= m;
}
目前尚不清楚您要做什么。我最好的理解是你有一个 82 字节的数组,你想反转数组的最低 37 位。由于一个字节是 8 位,所以你可以这样做:
byte[] myByteArray = new byte[82];
// invert lowest 32 bits, 8 at a time
for (int i = 0; i < 4; ++i) {
myByteArray[i] = (byte)(~myByteArray[i]);
}
// invert next five bits
myByteArray[4] = (byte) (
(myByteArray[4] & 0xE0) // top 3 bits unchanged
|
((~myByteArray[4)) & 0x1F) // bottom 5 bits inverted
);
这有效:
int nBits = 37;
int i = 0;
for (; i<nBits / 8; ++i)
myByteArray[i] = (byte)((byte) myByteArray[i] ^ 0xFF);
myByteArray[i] = (byte)(myByteArray[i] ^ ((0xFF >>> 5) ^ 0xFF));
是否与最后一行的 0xFF 进行最终 XOR 取决于您认为最高有效位是第一位(然后使用它)还是最后一位(然后省略它);
要反转特定的 37 位,随机选择:
// array of 82 bytes with 37 selected bits set to 1, all the rest zero
// you could generate this programmatically as well if you need a different
// set of bits each time, but your question implies you don't
byte[] mask = { 0x00, 0x01, 0x02, 0x80, .... 0x00 };
for (int i=0; i<myByteArray.length; i++)
{
myByteArray[i] ^= mask[i];
}
使用位异或运算符^
。异或的真值表是
M a s k
| 0 | 1
D -+---+---
a 0| 0 | 1
t -+---+---
a 1| 1 | 0
只要掩码中有 1,数据中的相应位就会被翻转。