Skip to content

Instantly share code, notes, and snippets.

@SteadBytes
Created April 11, 2020 07:02
Show Gist options
  • Save SteadBytes/fe93693811302fa6d3b7fae9ca445eb0 to your computer and use it in GitHub Desktop.
Save SteadBytes/fe93693811302fa6d3b7fae9ca445eb0 to your computer and use it in GitHub Desktop.
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
// Returning Result types would be preferable to throwing exceptions however this is currently not
// supported https://github.com/Kotlin/KEEP/blob/master/proposals/stdlib/result.md#limitations
fun bin(ch: Char): Int = when (ch) {
in '0'..'9' -> ch - '0'
in 'A'..'F' -> ch - 'A' + 10
in 'a'..'f' -> ch - 'a' + 10
else -> throw(IllegalArgumentException("'$ch' is not a valid hex character"))
}
fun hex(bytes: ByteArray): String {
return bytes.joinToString("") { "%02x".format(it.toInt() and 0XFF) }
}
fun xeh(hexStr: String): ByteArray {
// Remove whitespace and optional 0x prefix
val digits = hexStr.replace("\\s".toRegex(), "").replace("^0x".toRegex(), "")
if (digits.length % 2 != 0) {
throw IllegalArgumentException("Hex values must have an even number of nibbles")
}
return digits.chunked(2).map { ((bin(it[0]) shl 4) + bin(it[1])).toByte() }.toByteArray()
}
@RunWith(value = Parameterized::class)
class XehConversionTest(private val hexStr: String) {
@Test
fun `test xeh conversion`() {
assertEquals(
byteArrayOf(
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
).toList(),
xeh(hexStr).toList()
)
}
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{index}: xeh({0})")
fun data(): List<String> {
return arrayListOf(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"0001 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f"
).toList()
}
}
}
@RunWith(value = Parameterized::class)
class XehInvalidConversionTest(private val hexStr: String) {
@Test
fun `test xeh conversion throws`() {
assertFailsWith(IllegalArgumentException::class) {
xeh(hexStr)
}
}
companion object {
@JvmStatic
@Parameterized.Parameters()
fun data(): List<String> {
return arrayListOf(
"Not a hex string",
"0x00120" // Odd number of digits
).toList()
}
}
}
class HexConversionTest {
@Test
fun `hex conversion`() {
val bytes = byteArrayOf(
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
)
assertEquals(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
hex(bytes)
)
}
@Test
fun `test hex-xeh roundtrip`() {
val bytes = byteArrayOf(
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
)
assertEquals(xeh(hex(bytes)).toList(), bytes.toList())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment