Home > Back-end >  Increment a counter inside a byte array
Increment a counter inside a byte array

Time:02-08

I have an array of 5 bytes (fixed length). First 21 bits represent a counter and the rest 19 some id. I need to increment the counter by one. How do I do that?

CodePudding user response:

This answer is based on the memory layout as I understand it from the OP's comments:

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

Then

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);

should do the trick.

CodePudding user response:

I'm not sure I solved your problem. Since the memory layout is not described in detail, I assumed a layout. You can obtain the counter, increase it by 1, and then set the counter. If the layout is as desired, it needs to be fully tested. I'm not dealing with data overflow situations, and you may need to add some restrictions.

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();
    }
}

CodePudding user response:

I'm not sure I solved your problem.

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
    }
    
}
  •  Tags:  
  • Related