Есть ли лучший / более короткий способ создания массива байтов из константного шестнадцатеричного кода, чем версия ниже?
byteArrayOf(0xA1.toByte(), 0x2E.toByte(), 0x38.toByte(), 0xD4.toByte(), 0x89.toByte(), 0xC3.toByte())
Я попытался поставить 0xA1 без .toByte(), но получил жалобу синтаксическая ошибка о integer literal does not conform to the expected type Byte. Ввод целого числа - это нормально, но я предпочитаю шестнадцатеричную форму, поскольку мой источник - шестнадцатеричная строка. Приветствуются любые подсказки. Спасибо!





Проблема в том, что байты в Kotlin подписаны, что означает, что они могут представлять только значения в диапазоне [-128, 127]. Вы можете проверить это, создав ByteArray следующим образом:
val limits = byteArrayOf(-0x81, -0x80, -0x79, 0x00, 0x79, 0x80)
Только первое и последнее значения вызовут ошибку, потому что они выходят за пределы допустимого диапазона на 1.
Это то же поведение как в Java, и решение, вероятно, будет в используйте больший тип числа, если ваши значения не подходят для Byte (или смещают их на 128 и т. д.).
Боковое примечание: если вы распечатаете содержимое массива, созданного с помощью вызовов 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
как вариант вы можете создать простую функцию
fun byteArrayOfInts(vararg ints: Int) = ByteArray(ints.size) { pos -> ints[pos].toByte() }
и использовать это
val arr = byteArrayOfInts(0xA1, 0x2E, 0x38, 0xD4, 0x89, 0xC3)
Если бы все ваши байты были меньше или равны 0x7F, вы могли бы поместить их напрямую:
byteArrayOf(0x2E, 0x38)
Если вам нужно использовать байты больше, чем 0x7F, вы можете использовать литералы без знака, чтобы создать UByteArray, а затем преобразовать его обратно в ByteArray:
ubyteArrayOf(0xA1U, 0x2EU, 0x38U, 0xD4U, 0x89U, 0xC3U).toByteArray()
Я думаю, что это намного лучше, чем добавление .toByte() к каждому элементу, и также нет необходимости определять пользовательскую функцию.
Однако неподписанные типы Kotlin - это экспериментальная функция, поэтому у вас могут возникнуть проблемы с предупреждениями.