在字节数组中增加一个计数器
Increment a counter inside a byte array
我有一个 5 字节的数组(固定长度)。前 21 位代表一个计数器,其余 19 位代表一些 id。我需要将计数器加一。我该怎么做?
我不确定我是否解决了您的问题。由于没有详细描述内存布局,我假设了一个布局。您可以获取计数器,将其加 1,然后设置计数器。如果布局符合要求,则需要对其进行全面测试。我不是在处理数据溢出的情况,你可能需要添加一些限制。
public class Test {
public static void main(String[] args) {
byte[] bytes = new byte[5];
bytes[2] = 5;
for (int i = 0; i <= 0x1fffff; i++) {
setCount(bytes, i);
if (getCount(bytes) != i) {
System.out.println(i);
debug(bytes);
}
}
}
public static int getCount(byte[] bytes) {
return ((bytes[2] >> 3) & 0x1f) + ((bytes[1] << 5) & 0x1fff) + ((bytes[0] << 13) & 0x1fffff);
}
public static void setCount(byte[] bytes, int count) {
bytes[0] = (byte) (count >> 13 & 0xff);
bytes[1] = (byte) (count >> 5 & 0xff);
bytes[2] = (byte) ((bytes[2] & 0x7) + ((count & 0x1f) << 3));
}
public static void debug(byte[] bytes) {
for (byte b : bytes) {
for (int i = 7; i >= 0; i--) {
System.out.print(b >> i & 1);
}
System.out.print(" ");
}
System.out.println();
System.out.println("Count:" + getCount(bytes));
}
public static void printInt(int num) {
for (int i = 31; i >= 0; i--) {
System.out.print(num >> i & 1);
}
System.out.println();
}
}
我不确定我是否解决了你的问题。
public class Main
{
public static void main(String[] args)
{
//################
//# BIG ENDIAN #
//################
//initial counter == 1 (b0000_0000_0000_0000_0000_1)
//initial ids == 3 (b000_0000_0000_0000_0011)
byte[] array = { 0, 0, 8, 0, 3 };
int counter = ((array[0] & 0xFF) << 13)
| ((array[1] & 0xFF) << 5)
| ((array[2] & 0xF8) >> 3);
System.out.println(counter); //1
++counter;
System.out.println(counter); //2
//Repack the counter into the array.
array[0] = (byte)((counter & 0x1FE000) >> 13);
array[1] = (byte)((counter & 0x1FE0) >> 5);
array[2] = (byte)(((counter & 0x1F) << 3)| (array[2] & 0x7));
System.out.println(Arrays.toString(array)); //[0, 0, 16, 0, 3]
//Retry & Verify
counter = ((array[0] & 0xFF) << 13) //Same as above. Nothing is changed.
| ((array[1] & 0xFF) << 5)
| ((array[2] & 0xF8) >> 3);
System.out.println(counter); //2
++counter;
System.out.println(counter); //3
//###################
//# LITTLE ENDIAN #
//###################
//initial ids == 3 (b0000_0000_0000_0000_011)
//initial counter == 1 (b0_0000_0000_0000_0000_0001)
byte[] arr = { 0, 0, 96, 0, 1 };
counter = ((arr[2] & 0x1F) << 16)
| ((arr[3] & 0xFF) << 8)
| (arr[4] & 0xFF);
System.out.println(counter); //1
++counter;
System.out.println(counter); //2
//Repack the counter into the array.
arr[2] = (byte)((arr[2] & 0xE0) | ((counter & 0x1F0000) >> 16));
arr[3] = (byte)((counter & 0xFF00) >> 8);
arr[4] = (byte)(counter & 0xFF);
System.out.println(Arrays.toString(arr)); //[0, 0, 96, 0, 2]
//Retry & Verify
counter = ((arr[2] & 0x1F) << 16) //Same as above. Nothing is changed.
| ((arr[3] & 0xFF) << 8)
| (arr[4] & 0xFF);
System.out.println(counter); //2
++counter;
System.out.println(counter); //3
}
}
这个答案是基于我从 OP 的评论中了解到的内存布局:
array[0]: bits 0..7 are counter bits 0..7 (lsb)
array[1]: bits 0..7 are counter bits 8..15
array[2]: bits 0..4 are counter bits 16..20 (msb)
bits 5..7 are part of the id
array[3]: bits 0..7 are part of the id
array[3]: bits 0..7 are part of the id
然后
int byte0 = (int) array[0] & 0xff;
int byte1 = (int) array[1] & 0xff;
int byte2 = (int) array[2] & 0x1f;
int count = byte0 | (byte1 << 8) | (byte2 << 16);
count = (count+1) & 0x1fffff;
array[0] = (byte) (count & 0x0000ff);
array[1] = (byte) ((count & 0x00ff00) >> 8);
array[2] = (array[2] & 0xe0) | (byte) ((count & 0x1f0000) >> 16);
应该可以解决问题。
我有一个 5 字节的数组(固定长度)。前 21 位代表一个计数器,其余 19 位代表一些 id。我需要将计数器加一。我该怎么做?
我不确定我是否解决了您的问题。由于没有详细描述内存布局,我假设了一个布局。您可以获取计数器,将其加 1,然后设置计数器。如果布局符合要求,则需要对其进行全面测试。我不是在处理数据溢出的情况,你可能需要添加一些限制。
public class Test {
public static void main(String[] args) {
byte[] bytes = new byte[5];
bytes[2] = 5;
for (int i = 0; i <= 0x1fffff; i++) {
setCount(bytes, i);
if (getCount(bytes) != i) {
System.out.println(i);
debug(bytes);
}
}
}
public static int getCount(byte[] bytes) {
return ((bytes[2] >> 3) & 0x1f) + ((bytes[1] << 5) & 0x1fff) + ((bytes[0] << 13) & 0x1fffff);
}
public static void setCount(byte[] bytes, int count) {
bytes[0] = (byte) (count >> 13 & 0xff);
bytes[1] = (byte) (count >> 5 & 0xff);
bytes[2] = (byte) ((bytes[2] & 0x7) + ((count & 0x1f) << 3));
}
public static void debug(byte[] bytes) {
for (byte b : bytes) {
for (int i = 7; i >= 0; i--) {
System.out.print(b >> i & 1);
}
System.out.print(" ");
}
System.out.println();
System.out.println("Count:" + getCount(bytes));
}
public static void printInt(int num) {
for (int i = 31; i >= 0; i--) {
System.out.print(num >> i & 1);
}
System.out.println();
}
}
我不确定我是否解决了你的问题。
public class Main
{
public static void main(String[] args)
{
//################
//# BIG ENDIAN #
//################
//initial counter == 1 (b0000_0000_0000_0000_0000_1)
//initial ids == 3 (b000_0000_0000_0000_0011)
byte[] array = { 0, 0, 8, 0, 3 };
int counter = ((array[0] & 0xFF) << 13)
| ((array[1] & 0xFF) << 5)
| ((array[2] & 0xF8) >> 3);
System.out.println(counter); //1
++counter;
System.out.println(counter); //2
//Repack the counter into the array.
array[0] = (byte)((counter & 0x1FE000) >> 13);
array[1] = (byte)((counter & 0x1FE0) >> 5);
array[2] = (byte)(((counter & 0x1F) << 3)| (array[2] & 0x7));
System.out.println(Arrays.toString(array)); //[0, 0, 16, 0, 3]
//Retry & Verify
counter = ((array[0] & 0xFF) << 13) //Same as above. Nothing is changed.
| ((array[1] & 0xFF) << 5)
| ((array[2] & 0xF8) >> 3);
System.out.println(counter); //2
++counter;
System.out.println(counter); //3
//###################
//# LITTLE ENDIAN #
//###################
//initial ids == 3 (b0000_0000_0000_0000_011)
//initial counter == 1 (b0_0000_0000_0000_0000_0001)
byte[] arr = { 0, 0, 96, 0, 1 };
counter = ((arr[2] & 0x1F) << 16)
| ((arr[3] & 0xFF) << 8)
| (arr[4] & 0xFF);
System.out.println(counter); //1
++counter;
System.out.println(counter); //2
//Repack the counter into the array.
arr[2] = (byte)((arr[2] & 0xE0) | ((counter & 0x1F0000) >> 16));
arr[3] = (byte)((counter & 0xFF00) >> 8);
arr[4] = (byte)(counter & 0xFF);
System.out.println(Arrays.toString(arr)); //[0, 0, 96, 0, 2]
//Retry & Verify
counter = ((arr[2] & 0x1F) << 16) //Same as above. Nothing is changed.
| ((arr[3] & 0xFF) << 8)
| (arr[4] & 0xFF);
System.out.println(counter); //2
++counter;
System.out.println(counter); //3
}
}
这个答案是基于我从 OP 的评论中了解到的内存布局:
array[0]: bits 0..7 are counter bits 0..7 (lsb)
array[1]: bits 0..7 are counter bits 8..15
array[2]: bits 0..4 are counter bits 16..20 (msb)
bits 5..7 are part of the id
array[3]: bits 0..7 are part of the id
array[3]: bits 0..7 are part of the id
然后
int byte0 = (int) array[0] & 0xff;
int byte1 = (int) array[1] & 0xff;
int byte2 = (int) array[2] & 0x1f;
int count = byte0 | (byte1 << 8) | (byte2 << 16);
count = (count+1) & 0x1fffff;
array[0] = (byte) (count & 0x0000ff);
array[1] = (byte) ((count & 0x00ff00) >> 8);
array[2] = (array[2] & 0xe0) | (byte) ((count & 0x1f0000) >> 16);
应该可以解决问题。