将字节数组转换为十六进制字符串

Rap*_*ael 5 arrays string hex byte kotlin

令人惊讶的是(对我来说),这段代码没有做我想要的:

fun ByteArray.toHexString() : String {
    return this.joinToString("") { it.toString(16) }
}
Run Code Online (Sandbox Code Playgroud)

结果Byte是有符号的,所以你得到单个字节的负十六进制表示,这导致完全虚假的最终结果.

此外,Byte.toString不会填充您想要的前导零.

什么是最简单的(没有额外的库,理想情况下没有扩展名).最有效的修复?

Rol*_*and 20

正如我在Kotlin 1.3上你可能也UByte很快就会感兴趣(注意它是一个实验性功能.另见Kotlin 1.3M11.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') }
Run Code Online (Sandbox Code Playgroud)

格式化选项可能是最好的其他变体(但可能不那么易读......我总是忘记它是如何工作的,所以它绝对不容易记住(对我来说:-)):

fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }
Run Code Online (Sandbox Code Playgroud)

  • 如果有人需要一个不针对 JVM 的版本: ```fun ByteArray.toHexString() = joinToString("") { (0xFF and it.toInt()).toString(16).padStart(2, '0' ) }``` (11认同)

Rap*_*ael 10

printf 在这里做我们想要的:

fun ByteArray.toHexString() : String {
    return this.joinToString("") {
        java.lang.String.format("%02x", it)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @msrd0 这个问题没有 Java 标签。使用 KotlinJS,当我第一眼看到这样的答案时,我会很感激。 (3认同)
  • @Zackline 有趣的一点。是否出现了任何用于标记有关 JVM/JS/Android/Native 的 Kotlin 问题的约定? (3认同)

k31*_*159 5

如果将来有人搜索并发现这个问题,这里是 Kotlin 1.9+ 的答案。

有一个新的实验功能,fun ByteArray.toHexString(format: HexFormat = HexFormat.Default)

使用它非常简单:

byteArrayOf(0x0A, 0x0B, 0x0C).toHexString() returns "0x0b0c"
Run Code Online (Sandbox Code Playgroud)

您可以自定义它:

val hexFormat = HexFormat { bytes { byteSeparator = " "; upperCase = true } }
byteArrayOf(0x0A, 0x0B, 0x0C).toHexString(hexFormat) returns "0A 0B 0C"
Run Code Online (Sandbox Code Playgroud)