9

Here is my code :

Int -> ByteArray

private fun write4BytesToBuffer(buffer: ByteArray, offset: Int, data: Int) {
    buffer[offset + 0] = (data shr 24).toByte()
    buffer[offset + 1] = (data shr 16).toByte()
    buffer[offset + 2] = (data shr 8).toByte()
    buffer[offset + 3] = (data shr 0).toByte()
}

ByteArray -> Int

private fun read4BytesFromBuffer(buffer: ByteArray, offset: Int): Int {
    return (buffer[offset + 0].toInt() shl 24) or
           (buffer[offset + 1].toInt() shl 16) or
           (buffer[offset + 2].toInt() shl 8) or
           (buffer[offset + 3].toInt() and 0xff)
}

It works without any problem for any value between -32,768 and 32,767. However, it doesn't work with larger values. For example :

val buffer = ByteArray(10)
write4BytesToBuffer(buffer, 0, 324)
read4BytesFromBuffer(buffer, 0) // It returns 324 ***OK***

val buffer = ByteArray(10)
write4BytesToBuffer(buffer, 0, 40171)
read4BytesFromBuffer(buffer, 0) // It returns -25365 ***ERROR***

Do you see where I went wrong?

Greelings
  • 4,964
  • 7
  • 34
  • 70
  • 1
    You can use Java's `ByteBuffer ` as described here: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java – David Soroko Apr 20 '21 at 13:54

4 Answers4

13

Here is the solution.

Int -> ByteArray

private fun write4BytesToBuffer(buffer: ByteArray, offset: Int, data: Int) {
    buffer[offset + 0] = (data shr 0).toByte()
    buffer[offset + 1] = (data shr 8).toByte()
    buffer[offset + 2] = (data shr 16).toByte()
    buffer[offset + 3] = (data shr 24).toByte()
}

Or in a shorter way

for (i in 0..3) buffer[offset + i] = (data shr (i*8)).toByte()

ByteArray -> Int

private fun read4BytesFromBuffer(buffer: ByteArray, offset: Int): Int {
    return (buffer[offset + 3].toInt() shl 24) or
           (buffer[offset + 2].toInt() and 0xff shl 16) or
           (buffer[offset + 1].toInt() and 0xff shl 8) or
           (buffer[offset + 0].toInt() and 0xff)
}
Greelings
  • 4,964
  • 7
  • 34
  • 70
  • I am not sure it's correct, I have not tried it but I will thumbup before trying it because u r the first one to do this, I have been looking for an answer for a complete day :0 – Mohammad Elsayed Aug 17 '21 at 00:41
  • @MohammadElsayed It's correct. I tested it in every way. :) But if not, please let me know. – Greelings Aug 17 '21 at 09:52
  • 2
    I wrote `for (i in 0..3) buffer[offset + i] = (data shr (i*8)).toByte()` – Guss Oct 06 '21 at 14:46
8

I'd just use java.nio.ByteBuffer -

fun intToBytes(i: Int): ByteArray =
    ByteBuffer.allocate(Int.SIZE_BYTES).putInt(i).array()

fun bytesToInt(bytes: ByteArray): Int =
    ByteBuffer.wrap(bytes).int
0cd
  • 1,729
  • 3
  • 15
  • 24
7

Here is an one liner that will give you a ByteArray:

fun numberToByteArray (data: Number, size: Int = 4) : ByteArray = 
    ByteArray (size) {i -> (data.toLong() shr (i*8)).toByte()}

Optionally setting the number of bytes (size), you can convert Shorts, Ints, Longs.

Just call it like this:

var yourByteArray = numberToByteArray (yourNumberHere)
plpsanchez
  • 339
  • 4
  • 10
  • Should "item.toLong()" be "data.toLong()"? – Awesomeness Nov 16 '21 at 14:03
  • Damn, Kotlin has no in-built class for converting types to bytes like C#'s `BitConverter` which existed for like 2 decades, and I have to create these methods for each type? This is unexpected... I thought this is a very basic need. – Damn Vegetables Dec 03 '21 at 01:54
0

you can write an extension function for that:

fun ByteArray.getIntAt(i: Int): Int {
    return (this[i].toInt() and 0xFF) or
            ((this[i + 1].toInt() and 0xFF) shl 8) or
            ((this[i + 2].toInt() and 0xFF) shl 16) or
            ((this[i + 3].toInt() and 0xFF) shl 24)
}

now you can use it:

val myInt = myByteArr.getIntAt(myIndex)

and vice versa:

private fun Int.toByteArray(): ByteArray {
    return byteArrayOf(
        (this and 0xFF).toByte(),
        ((this shr 8) and 0xFF).toByte(),
        ((this shr 16) and 0xFF).toByte(),
        ((this shr 24) and 0xFF).toByte()
    )
}

and use it:

val myByteArray = myInt.toByteArray()
Ohad Cohen
  • 5,756
  • 3
  • 39
  • 36