1

I have a variable of type ByteArray:

val byteArray: ByteArray?

I am currently accessing its first byte, indexing it as follows: byteArray[0]. I want to be able to get the first two bytes on this byte array. Should I get byte 0 and 1 and then append, or can I do byteArray[0:1] somehow? I am very new to Java and Kotlin and any guidance is appreciated.

I need to be able to get the first two bytes , so then I can get bits 0 to 16 and convert it to an integer. I use this to convert bytes to binary string:

  `String.format("%8s", Integer.toBinaryString(inByte & 0xFF)).replace(' ', '0');`
  • It's unclear what you want to do, or what the end result would be. Are you looking for a `short` (16-bit integer) value? Or something else, if so what? The word "append" doesn't make sense to me in the context of bytes. – Mark Rotteveel Oct 26 '21 at 12:07
  • why getting `get(0)`, `get(1)` is a problem? I can provide answer here, but why to ask question instead of simply moving forward? Just go, do your job, and then optimize. If you are at this point - I mean optimizing - please provide more code... – Michał Zaborowski Oct 26 '21 at 12:09
  • I apologize. To be more clear: I want to get the first two bytes in that byte array, so I can access the first 16 bits and convert it to integer. –  Oct 26 '21 at 12:09
  • Your first suggestion, but I'd suggest you read up on how arrays function in Java – Tschallacka Oct 26 '21 at 12:09
  • besides that - please provide whole problem - it can be you are looking for solution to the problem that can be avoided... – Michał Zaborowski Oct 26 '21 at 12:10
  • 1
    @MichałZaborowski I should have added more context. I need bit 0-16 to convert it to an integer. I wouldn't know how to do that if I get byte 0 first and then byte 1, without concatenating them. I was wondering if there is a direct way to get byte 0 TO 1 at once. –  Oct 26 '21 at 12:11
  • @Sweeper Thank you for that part! but the byte array has 4 bytes, I only need to convert the first two. That's what I didn't know how to best access –  Oct 26 '21 at 12:26
  • @StephM My answer _does_ only access the first two. Is there anything wrong with that? Did you expect it to be in little endian perhaps? – Sweeper Oct 26 '21 at 12:32

4 Answers4

8

If you want an integer from the first two bytes, just use a ByteBuffer:

// x is of type Short
val x = ByteBuffer.wrap(byteArray).short

This will only read the first two bytes of the array, in big endian order (you can change this with order), or throw an exception if there are fewer than 2 bytes in the array.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Thank you!! The order of the bytes is little endian, but the bits are big endian. So I have 4 bytes out of which I need to read byte 0 and 1 in that order, and then the 16bits are read with Most Significant bit being left (Big endian) –  Oct 26 '21 at 12:50
  • 3
    @StephM Just add `.order(ByteOrder.LITTLE_ENDIAN)` before `.short` then. [Are you sure bit order matters here?](https://stackoverflow.com/a/16803427/5133585) – Sweeper Oct 26 '21 at 12:54
3

You can use destructuring to access the first two bytes in an array.

To convert them to an integer, you can use toInt to convert the first byte, shl to bitshift it left by 8 bits, and then add the 2nd byte.

fun main() {
    val byteArray = byteArrayOf(0b00000001, 0b00000010, 0b00000011)
    val (firstByte, secondByte) = byteArray.toUByteArray()
    val firstTwoBytes = (firstByte.toInt() shl 8) + secondByte.toInt()
    println(firstByte)      // 00000001
    println(secondByte)     // 00000010
    println(firstTwoBytes)  // 0000000100000010
}

Output:

1
2
258

I am converting the signed byte array toUByteArray() here, because toInt() preserves the numeric value of the signed bytes, meaning negative bytes would produce negative integers, which is not what you want if you are only concerned with the raw bits. Using unsigned bytes is what you really want here.

If you wanted to avoid converting the whole array, you could convert only the first two bytes by doing this instead:

val firstTwoBytes = (firstByte.toUByte().toInt() shl 8) + secondByte.toUByte().toInt()
Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
1

Big Endian

byte[] bytes = new byte[] { 1, 2, 3, 4 };
int shorty = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF);

Little Endian

byte[] bytes = new byte[] { 1, 2, 3, 4 };
int shorty = ((bytes[1] & 0xFF) << 8) | (bytes[0] & 0xFF);
Darkman
  • 2,941
  • 2
  • 9
  • 14
0

You did not specify the order of the bits in your bytes. Depending on whether you want big endian or small endian use

int result = ((int)byteArray[1])*256+((int)byteArray[0])

or

int result = ((int)byteArray[2])*256+((int)byteArray[1])
Queeg
  • 7,748
  • 1
  • 16
  • 42