All Downloads are FREE. Search and download functionalities are using the official Maven repository.

library.HexExtensions.kt Maven / Gradle / Ivy

Go to download

This is a kotlin based domain specific language (dsl), to quickly and intuitively write custom DoIP ECU simulations.

There is a newer version: 0.15.1
Show newest version
package library

import java.nio.Buffer
import java.nio.ByteBuffer
import kotlin.math.min

fun String.decodeHex(): ByteArray {
    // Maximum size for the resulting bytearray is string-length / 2
    val bb = ByteBuffer.allocate(this.length / 2)

    var nibble: Int
    var b = 0
    var counter = 0
    for (i in this.indices) {
        val c = this[i]
        nibble = if (c in '0'..'9') {
            c - '0'
        } else if (c in 'A'..'F') {
            c - 'A' + 10
        } else if (c in 'a'..'f') {
            c - 'a' + 10
        } else {
            // Non-hex character, ignore
            continue
        }

        if (counter++ % 2 == 0) {
            // msb
            b = nibble shl 4
        } else {
            b = b or nibble
            bb.put(b.toByte())
        }
    }

    if (counter % 2 != 0) {
        throw IllegalArgumentException("Length of hex chars isn't even in string '$this'")
    }

    // cast to buffer, so it runs on jdk1.8 and jdk 11+
    // cause: jdk 11's bytebuffer implements its own flip method with a different return type
    (bb as Buffer).flip()
    val buf = ByteArray((bb as Buffer).limit())
    bb.get(buf)
    return buf
// Simpler yet worse performing version
//    val s = this.replace(" ", "")
//    check(s.length % 2 == 0) { "String must have an even length" }
//    return s.chunked(2)
//        .map { it.toInt(16).toByte() }
//        .toByteArray()
}

fun String.encodedAsHexString(separator: String = " "): String =
    this.encodeToByteArray().toHexString(separator)

private val nibbleToHex = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')

fun ByteArray.toHexString(separator: String = " ", limit: Int = Integer.MAX_VALUE, limitExceededSuffix: String = "..."): String {
    val len = min(limit, this.size)
    if (len == 0) {
        if (this.size > limit) {
            return limitExceededSuffix
        }
        return ""
    }
    val sb = StringBuilder((len * 2) + ((len - 1) * separator.length))
    for (i in 0 until len) {
        if (separator.isNotEmpty() && i > 0) {
            sb.append(separator)
        }
        sb.append(nibbleToHex[(this[i].toInt() and 0xF0) shr 4])
        sb.append(nibbleToHex[this[i].toInt() and 0x0F])
    }
    if (this.size > limit) {
        sb.append(limitExceededSuffix)
    }
    return sb.toString()
}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy