mirai/mirai-core-utils/src/commonMain/kotlin/Bytes.kt

68 lines
2.2 KiB
Kotlin
Raw Normal View History

/*
* Copyright 2019-2020 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:JvmMultifileClass
@file:JvmName("MiraiUtils")
package net.mamoe.mirai.utils
@JvmOverloads
public fun generateImageId(md5: ByteArray, format: String = "mirai"): String {
return """{${generateUUID(md5)}}.$format"""
}
public fun generateUUID(md5: ByteArray): String {
return "${md5[0, 3]}-${md5[4, 5]}-${md5[6, 7]}-${md5[8, 9]}-${md5[10, 15]}"
}
@JvmSynthetic
internal operator fun ByteArray.get(rangeStart: Int, rangeEnd: Int): String = buildString {
for (it in rangeStart..rangeEnd) {
append(this@get[it].fixToString())
}
}
private fun Byte.fixToString(): String {
return when (val b = this.toInt() and 0xff) {
in 0..15 -> "0${this.toString(16).toUpperCase()}"
else -> b.toString(16).toUpperCase()
}
}
@OptIn(ExperimentalUnsignedTypes::class)
@JvmOverloads
@Suppress("DuplicatedCode") // false positive. foreach is not common to UByteArray and ByteArray
public fun ByteArray.toUHexString(
separator: String = " ",
offset: Int = 0,
length: Int = this.size - offset
): String {
this.checkOffsetAndLength(offset, length)
if (length == 0) {
return ""
}
val lastIndex = offset + length
return buildString(length * 2) {
this@toUHexString.forEachIndexed { index, it ->
if (index in offset until lastIndex) {
var ret = it.toUByte().toString(16).toUpperCase()
if (ret.length == 1) ret = "0$ret"
append(ret)
if (index < lastIndex - 1) append(separator)
}
}
}
}
public fun ByteArray.checkOffsetAndLength(offset: Int, length: Int) {
require(offset >= 0) { "offset shouldn't be negative: $offset" }
require(length >= 0) { "length shouldn't be negative: $length" }
require(offset + length <= this.size) { "offset ($offset) + length ($length) > array.size (${this.size})" }
}