mirai/mirai-core-utils/src/commonMain/kotlin/Conversions.kt
Him188 bcdff1336b
Kotlin 1.5 and dependencies updates (#1246)
* Kotlin 1.5 and dependencies updates

* Update mirai-console ref

* Use Kotlin 1.5.10

* 2.7-M1-dev-3

* Update console ref
2021-05-27 14:39:13 +08:00

174 lines
4.9 KiB
Kotlin

/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE", "unused")
@file:JvmMultifileClass
@file:JvmName("MiraiUtils")
package net.mamoe.mirai.utils
/*
* 类型转换 Utils.
* 这些函数为内部函数, 可能会改变
*/
/**
* 255 -> 00 FF
*/
public fun Short.toByteArray(): ByteArray = with(toInt()) {
byteArrayOf(
(shr(8) and 0xFF).toByte(),
(shr(0) and 0xFF).toByte()
)
}
/**
* 255 -> 00 00 00 FF
*/
public fun Int.toByteArray(): ByteArray = byteArrayOf(
ushr(24).toByte(),
ushr(16).toByte(),
ushr(8).toByte(),
ushr(0).toByte()
)
/**
* 255 -> 00 00 00 FF
*/
public fun Long.toByteArray(): ByteArray = byteArrayOf(
(ushr(56) and 0xFF).toByte(),
(ushr(48) and 0xFF).toByte(),
(ushr(40) and 0xFF).toByte(),
(ushr(32) and 0xFF).toByte(),
(ushr(24) and 0xFF).toByte(),
(ushr(16) and 0xFF).toByte(),
(ushr(8) and 0xFF).toByte(),
(ushr(0) and 0xFF).toByte()
)
public fun Int.toUHexString(separator: String = " "): String = this.toByteArray().toUHexString(separator)
/**
* 255 -> 00 FF
*/
public fun UShort.toByteArray(): ByteArray = with(toUInt()) {
byteArrayOf(
(shr(8) and 255u).toByte(),
(shr(0) and 255u).toByte()
)
}
public fun Short.toUHexString(separator: String = " "): String = this.toUShort().toUHexString(separator)
public fun UShort.toUHexString(separator: String = " "): String =
this.toInt().shr(8).toUShort().toUByte().toUHexString() + separator + this.toUByte().toUHexString()
public fun ULong.toUHexString(separator: String = " "): String =
this.toLong().toUHexString(separator)
public fun Long.toUHexString(separator: String = " "): String =
this.ushr(32).toUInt().toUHexString(separator) + separator + this.toUInt().toUHexString(separator)
/**
* 255 -> 00 FF
*/
public fun UByte.toByteArray(): ByteArray = byteArrayOf((this and 255u).toByte())
public fun UByte.toUHexString(): String = this.toByte().toUHexString()
/**
* 255u -> 00 00 00 FF
*/
public fun UInt.toByteArray(): ByteArray = byteArrayOf(
(shr(24) and 255u).toByte(),
(shr(16) and 255u).toByte(),
(shr(8) and 255u).toByte(),
(shr(0) and 255u).toByte()
)
/**
* 转 [ByteArray] 后再转 hex
*/
public fun UInt.toUHexString(separator: String = " "): String = this.toByteArray().toUHexString(separator)
/**
* 转无符号十六进制表示, 并补充首位 `0`.
* 转换结果示例: `FF`, `0E`
*/
public fun Byte.toUHexString(): String = this.toUByte().fixToUHex()
/**
* 转无符号十六进制表示, 并补充首位 `0`.
*/
public fun Byte.fixToUHex(): String = this.toUByte().fixToUHex()
/**
* 转无符号十六进制表示, 并补充首位 `0`.
*/
public fun UByte.fixToUHex(): String =
if (this.toInt() in 0..15) "0${this.toString(16).uppercase()}" else this.toString(16).uppercase()
public fun String.hexToBytes(): ByteArray =
this.split(" ")
.asSequence()
.filterNot { it.isEmpty() }
.map { s -> s.toUByte(16).toByte() }
.toList()
.toByteArray()
/**
* 每 2 char 为一组, 转换 Hex 为 [ByteArray]
*
* 这个方法很累, 不建议经常使用.
*/
public fun String.chunkedHexToBytes(): ByteArray =
this.asSequence().chunked(2).map { (it[0].toString() + it[1]).toUByte(16).toByte() }.toList().toByteArray()
/**
* 删掉全部空格和换行后每 2 char 为一组, 转换 Hex 为 [ByteArray].
*/
public fun String.autoHexToBytes(): ByteArray =
this.replace("\n", "").replace(" ", "").asSequence().chunked(2).map {
(it[0].toString() + it[1]).toUByte(16).toByte()
}.toList().toByteArray()
/**
* 将无符号 Hex 转为 [UByteArray], 有根据 hex 的 [hashCode] 建立的缓存.
*/
public fun String.hexToUBytes(): UByteArray =
this.split(" ")
.asSequence()
.filterNot { it.isEmpty() }
.map { s -> s.toUByte(16) }
.toList()
.toUByteArray()
/**
* 将 [this] 前 4 个 [Byte] 的 bits 合并为一个 [Int]
*
* 详细解释:
* 一个 [Byte] 有 8 bits
* 一个 [Int] 有 32 bits
* 本函数将 4 个 [Byte] 的 bits 连接得到 [Int]
*/
public fun ByteArray.toUInt(): UInt =
(this[0].toUInt().and(255u) shl 24) + (this[1].toUInt().and(255u) shl 16) + (this[2].toUInt()
.and(255u) shl 8) + (this[3].toUInt().and(
255u
) shl 0)
public fun ByteArray.toUShort(): UShort =
((this[0].toUInt().and(255u) shl 8) + (this[1].toUInt().and(255u) shl 0)).toUShort()
public fun ByteArray.toInt(): Int =
(this[0].toInt().and(255) shl 24) + (this[1].toInt().and(255) shl 16) + (this[2].toInt()
.and(255) shl 8) + (this[3].toInt().and(
255
) shl 0)