在Kotlin中创建ByteArray

You*_* Qi 12 kotlin

从常量十六进制创建字节数组是否有更好/更短的方式比下面的版本?

byteArrayOf(0xA1.toByte(), 0x2E.toByte(), 0x38.toByte(), 0xD4.toByte(), 0x89.toByte(), 0xC3.toByte())
Run Code Online (Sandbox Code Playgroud)

我试图把0xA1没有,.toByte()但我收到语法错误投诉说integer literal does not conform to the expected type Byte.放整数很好,但我更喜欢十六进制形式,因为我的源是十六进​​制字符串.任何提示将不胜感激.谢谢!

小智 12

作为选项,您可以创建简单的功能

fun byteArrayOfInts(vararg ints: Int) = ByteArray(ints.size) { pos -> ints[pos].toByte() }
Run Code Online (Sandbox Code Playgroud)

并使用它

val arr = byteArrayOfInts(0xA1, 0x2E, 0x38, 0xD4, 0x89, 0xC3)
Run Code Online (Sandbox Code Playgroud)


Mil*_*k27 9

如果您的所有字节均小于或等于0x7F,则可以将其直接放入:

byteArrayOf(0x2E, 0x38)
Run Code Online (Sandbox Code Playgroud)

如果您需要使用大于的字节0x7F,则可以使用无符号文字生成a UByteArray,然后将其转换回a ByteArray

ubyteArrayOf(0xA1U, 0x2EU, 0x38U, 0xD4U, 0x89U, 0xC3U).toByteArray()
Run Code Online (Sandbox Code Playgroud)

我认为这比.toByte()在每个元素上附加要好得多,并且也不需要定义自定义函数。

但是,Kotlin的无符号类型是实验性功能,因此警告可能会有些麻烦。


小智 7

我只是做:

val bytes = listOf(0xa1, 0x2e, 0x38, 0xd4, 0x89, 0xc3)
    .map { it.toByte() }
    .toByteArray()
Run Code Online (Sandbox Code Playgroud)


zsm*_*b13 5

问题是Kotlin中的字节已签名,这意味着它们只能表示[-128,127]范围内的值。您可以通过创建ByteArray如下代码来进行测试:

val limits = byteArrayOf(-0x81, -0x80, -0x79, 0x00, 0x79, 0x80)
Run Code Online (Sandbox Code Playgroud)

只有第一个和最后一个值会产生错误,因为它们超出有效范围1。

这与Java中的行为相同,并且解决方案可能是如果数值不适合(或将其偏移128等),则使用更大的数字类型Byte


附带说明:如果打印通过toInt调用创建的数组的内容,则会看到大于127的值已翻转为负数:

val bytes = byteArrayOf(0xA1.toByte(), 0x2E.toByte(), 0x38.toByte(), 0xD4.toByte(), 0x89.toByte(), 0xC3.toByte())
println(bytes.joinToString()) // -95, 46, 56, -44, -119, -61
Run Code Online (Sandbox Code Playgroud)