Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ByteArray and String extension to add hexadecimal methods in Kotlin
private val HEX_CHARS = "0123456789ABCDEF".toCharArray()
fun ByteArray.toHex() : String{
val result = StringBuffer()
forEach {
val octet = it.toInt()
val firstIndex = (octet and 0xF0).ushr(4)
val secondIndex = octet and 0x0F
result.append(HEX_CHARS[firstIndex])
result.append(HEX_CHARS[secondIndex])
}
return result.toString()
}
private val HEX_CHARS = "0123456789ABCDEF"
fun String.hexStringToByteArray() : ByteArray {
val result = ByteArray(length / 2)
for (i in 0 until length step 2) {
val firstIndex = HEX_CHARS.indexOf(this[i]);
val secondIndex = HEX_CHARS.indexOf(this[i + 1]);
val octet = firstIndex.shl(4).or(secondIndex)
result.set(i.shr(1), octet.toByte())
}
return result
}
@32bitkid

This comment has been minimized.

Copy link

commented Dec 14, 2017

probably not the best performance, but if you are looking for one-liners:

fun ByteArray.toHex() = this.joinToString(separator = "") { it.toInt().and(0xff).toString(16).padStart(2, '0') }
fun String.hexStringToByteArray() = ByteArray(this.length / 2) { this.substring(it * 2, it * 2 + 2).toInt(16).toByte() }
@Sloy

This comment has been minimized.

Copy link

commented Jan 5, 2018

Be careful, it only accepts uppercase strings.
It took me a half an hour to realize that my problem was there 🤦‍♂

@dkowis

This comment has been minimized.

Copy link

commented Aug 22, 2018

Another one liner:

byteArray.map { String.format("%02X", (it.toInt() and 0xFF)) }.joinToString(separator = "")
@kspar

This comment has been minimized.

Copy link

commented Nov 10, 2018

Or

byteArray.joinToString("") { String.format("%02X", (it.toInt() and 0xFF)) }
@dfpalomar

This comment has been minimized.

Copy link

commented Jan 8, 2019

I would also add some validation

if (firstIndex < 0) throw Exception("${this[i]} is not a valid Hex value")

same with secondIndex

@ZenLiuCN

This comment has been minimized.

Copy link

commented Feb 14, 2019

	fun ByteArray.toHexString()=this.joinToString(""){ String.format("%02X",(it.toInt() and 0xFF)) }
	fun String.byteArrayFromHexString()=this.chunked(2).map { it.toInt(16).toByte() }.toByteArray()

update for

//will handle Upper or Lower sequence
fun String.byteArrayFromHexString()=this.chunked(2).map { it.toUpperCase().toInt(16).toByte() }.toByteArray()

I more like this,inline or not take easy

val ByteArray.asHexLower inline get() = this.joinToString(separator = ""){ String.format("%02x",(it.toInt() and 0xFF))}
val ByteArray.asHexUpper inline get() = this.joinToString(separator = ""){ String.format("%02X",(it.toInt() and 0xFF))}
val String.hexAsByteArray inline get() = this.chunked(2).map { it.toUpperCase().toInt(16).toByte() }.toByteArray()

if make it more safe
I realy suggestion that better not throw Exception that not meanful,return null is may better choice

val String.tryHexAsByteArray inline get() = try{this.chunked(2).map { it.toUpperCase().toInt(16).toByte() }.toByteArray()}catch(e:Throwable){null}
//could be used as
func someAction(src:String){
    val bytes=src.tryHexAsByteArray?:throw Exception("not valid HEX string")
   //... do something with ByteArray
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.