package commons.stand object StringUtils { //极简方案(无边界处理,适合已知合法输入) fun simpleHexToByteArray(hexStr: String): ByteArray { require(hexStr.length % 2 == 0) { "16进制字符串长度必须为偶数" } return hexStr.chunked(2) .map { it.toInt(16).toByte() } .toByteArray() } //兼容所有输入格式,无崩溃风险 fun hexStringToByteArray(hexStr: String): ByteArray { // 1. 预处理:去除前缀(0x/0X)、空格,转为大写 val cleanedHex = hexStr.trim() .replaceFirst("^0x|^0X".toRegex(), "") // 移除前缀 .replace("\\s+".toRegex(), "") // 移除所有空格(如 "A1 B2" → "A1B2") .uppercase() // 2. 处理空字符串 if (cleanedHex.isEmpty()) return ByteArray(0) // 3. 处理奇数长度:末尾补0(如 "A1B" → "A1B0") val length = cleanedHex.length val paddedHex = if (length % 2 != 0) cleanedHex + "0" else cleanedHex // 4. 批量转换:每2个字符为一组,转成1个字节 return paddedHex.chunked(2) // 按2个字符分割(如 "A1B0" → ["A1", "B0"]) .map { chunk -> // 16进制字符串转字节(radix=16),toByte() 会自动处理 0-255 范围 chunk.toInt(radix = 16).toByte() } .toByteArray() } // 性能优化(大数据量场景) fun largeHexToByteArray(hexStr: String): ByteArray { val cleanedHex = hexStr.trim().replaceFirst("^0x|^0X".toRegex(), "").uppercase() if (cleanedHex.isEmpty()) return ByteArray(0) val length = cleanedHex.length val resultLength = (length + 1) / 2 // 向上取整(奇数长度也适配) val byteArray = ByteArray(resultLength) for (i in 0 until resultLength) { val high = cleanedHex[i * 2].digitToInt(16) // 高位字符(第1个) val low = if (i * 2 + 1 < length) cleanedHex[i * 2 + 1].digitToInt(16) else 0 // 低位字符(第2个,无则补0) byteArray[i] = (high * 16 + low).toByte() } return byteArray } /** * ByteArray 转 16进制字符串 * @param withPrefix 是否带 0x 前缀(默认 false) * @param withSpace 是否用空格分隔字节(默认 true,如 "A1 B2") * @param uppercase 是否大写(默认 true) */ fun byteToHexString( byteArray: ByteArray?, withPrefix: Boolean = false, withSpace: Boolean = false, uppercase: Boolean = true ): String { if (byteArray == null) return "" val hexChars = byteArray.joinToString(separator = if (withSpace) " " else "") { val hex = "%02x".format(it) // 每个字节转 2 位 16进制(不足补 0) if (uppercase) hex.uppercase() else hex } return if (withPrefix) "0x$hexChars" else hexChars /* val sb = StringBuilder() for (b in bytes) { sb.append(String.format("%02x", b)) } return sb.toString()*/ } }