Преобразование байтового массива в шестнадцатеричную строку - PullRequest
0 голосов
/ 07 сентября 2018

Удивительно (для меня), этот код не делает то, что я хочу:

fun ByteArray.toHexString() : String {
    return this.joinToString("") { it.toString(16) }
}

Оказывается, Byte имеет значение со знаком , поэтому вы получаете отрицательные шестнадцатеричные представления для отдельных байтов, что приводит к полностью фиктивному конечному результату.

Кроме того, Byte.toString не будет дополнять начальные нули, которые вы бы хотели здесь.

Что является самым простым (без дополнительных библиотек, в идеале без расширений), соотв. наиболее эффективное исправление?

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

printf делает то, что мы хотим здесь:

fun ByteArray.toHexString() : String {
    return this.joinToString("") {
        java.lang.String.format("%02x", it)
    }
}
0 голосов
/ 07 сентября 2018

Поскольку я работаю на Kotlin 1.3, вас также может заинтересовать UByte (обратите внимание, что это экспериментальная функция. См. Также Kotlin 1.3M1 и 1.3M2 объявление )

Например:

@ExperimentalUnsignedTypes // just to make it clear that the experimental unsigned types are used
fun ByteArray.toHexString() = asUByteArray().joinToString("") { it.toString(16).padStart(2, '0') }

Вариант форматирования, вероятно, является самым хорошим другим вариантом (но, возможно, не так легко читаемым ... и я всегда забываю, как он работает, так что это определенно не таклегко запомнить (для меня: -)):

fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }
0 голосов
/ 07 сентября 2018
fun ByteArray.toHexString() = joinToString("") {
    Integer.toUnsignedString(java.lang.Byte.toUnsignedInt(it), 16).padStart(2, '0')
}

К счастью, в Java есть методы toUnsignedString для Integer и Long. К сожалению, эти методы только на Integer и Long, поэтому вам необходимо сначала преобразовать каждый байт (используя Byte#toUnsignedInt).

...