mirror of
https://github.com/corda/corda.git
synced 2025-01-29 15:43:55 +00:00
CORDA-3175 Remove dependency on 3rd party javax.xml.bind library for simple hex parsing/printing. (#5412)
* Remove dependency on 2rd party javax.xml.bind library for simple hex parsing/printing. * Added unit test.
This commit is contained in:
parent
6202165957
commit
136600c91a
@ -10,7 +10,6 @@ import java.io.OutputStream
|
||||
import java.lang.Math.max
|
||||
import java.lang.Math.min
|
||||
import java.nio.ByteBuffer
|
||||
import javax.xml.bind.DatatypeConverter
|
||||
|
||||
/**
|
||||
* An abstraction of a byte array, with offset and size that does no copying of bytes unless asked to.
|
||||
@ -179,13 +178,60 @@ fun ByteArray.sequence(offset: Int = 0, size: Int = this.size) = ByteSequence.of
|
||||
/**
|
||||
* Converts this [ByteArray] into a [String] of hexadecimal digits.
|
||||
*/
|
||||
fun ByteArray.toHexString(): String = DatatypeConverter.printHexBinary(this)
|
||||
fun ByteArray.toHexString(): String = printHexBinary(this)
|
||||
|
||||
private val hexCode = "0123456789ABCDEF".toCharArray()
|
||||
private fun printHexBinary(data: ByteArray): String {
|
||||
val r = StringBuilder(data.size * 2)
|
||||
for (b in data) {
|
||||
r.append(hexCode[(b.toInt() shr 4) and 0xF])
|
||||
r.append(hexCode[b.toInt() and 0xF])
|
||||
}
|
||||
return r.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this [String] of hexadecimal digits into a [ByteArray].
|
||||
* @throws IllegalArgumentException if the [String] contains incorrectly-encoded characters.
|
||||
*/
|
||||
fun String.parseAsHex(): ByteArray = DatatypeConverter.parseHexBinary(this)
|
||||
fun String.parseAsHex(): ByteArray = parseHexBinary(this)
|
||||
|
||||
private fun parseHexBinary(s: String): ByteArray {
|
||||
val len = s.length
|
||||
|
||||
// "111" is not a valid hex encoding.
|
||||
if (len % 2 != 0) {
|
||||
throw IllegalArgumentException("hexBinary needs to be even-length: $s")
|
||||
}
|
||||
|
||||
val out = ByteArray(len / 2)
|
||||
|
||||
fun hexToBin(ch: Char): Int {
|
||||
if (ch in '0'..'9') {
|
||||
return ch - '0'
|
||||
}
|
||||
if (ch in 'A'..'F') {
|
||||
return ch - 'A' + 10
|
||||
}
|
||||
return if (ch in 'a'..'f') {
|
||||
ch - 'a' + 10
|
||||
} else -1
|
||||
}
|
||||
|
||||
var i = 0
|
||||
while (i < len) {
|
||||
val h = hexToBin(s[i])
|
||||
val l = hexToBin(s[i + 1])
|
||||
if (h == -1 || l == -1) {
|
||||
throw IllegalArgumentException("contains illegal character for hexBinary: $s")
|
||||
}
|
||||
|
||||
out[i / 2] = (h * 16 + l).toByte()
|
||||
i += 2
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
/**
|
||||
* Class is public for serialization purposes.
|
||||
|
@ -10,7 +10,6 @@ import net.corda.core.internal.hash
|
||||
import java.nio.charset.Charset
|
||||
import java.security.PublicKey
|
||||
import java.util.*
|
||||
import javax.xml.bind.DatatypeConverter
|
||||
|
||||
// This file includes useful encoding methods and extension functions for the most common encoding/decoding operations.
|
||||
|
||||
@ -31,7 +30,7 @@ fun ByteArray.toBase58(): String = Base58.encode(this)
|
||||
fun ByteArray.toBase64(): String = Base64.getEncoder().encodeToString(this)
|
||||
|
||||
/** Convert a byte array to a hex (Base16) capitalized encoded [String]. */
|
||||
fun ByteArray.toHex(): String = DatatypeConverter.printHexBinary(this)
|
||||
fun ByteArray.toHex(): String = toHexString()
|
||||
|
||||
// [String] encoders and decoders
|
||||
|
||||
@ -49,7 +48,7 @@ fun String.base58ToByteArray(): ByteArray = Base58.decode(this)
|
||||
fun String.base64ToByteArray(): ByteArray = Base64.getDecoder().decode(this)
|
||||
|
||||
/** Hex-String to [ByteArray]. Accept any hex form (capitalized, lowercase, mixed). */
|
||||
fun String.hexToByteArray(): ByteArray = DatatypeConverter.parseHexBinary(this)
|
||||
fun String.hexToByteArray(): ByteArray = parseAsHex()
|
||||
|
||||
// Encoding changers
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
package net.corda.core.utilities
|
||||
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.internal.declaredField
|
||||
import org.assertj.core.api.Assertions.catchThrowable
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertSame
|
||||
import org.junit.Test
|
||||
import java.nio.ByteBuffer
|
||||
@ -42,4 +45,17 @@ class ByteArraysTest {
|
||||
check(byteArrayOf(), seq.slice(2, 2))
|
||||
check(byteArrayOf(), seq.slice(2, 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test hex parsing strictly uppercase`() {
|
||||
val HEX_REGEX = "^[0-9A-F]+\$".toRegex()
|
||||
|
||||
val privacySalt = net.corda.core.contracts.PrivacySalt()
|
||||
val privacySaltAsHexString = privacySalt.bytes.toHexString()
|
||||
Assert.assertTrue(privacySaltAsHexString.matches(HEX_REGEX))
|
||||
|
||||
val stateRef = StateRef(SecureHash.randomSHA256(), 0)
|
||||
val txhashAsHexString = stateRef.txhash.bytes.toHexString()
|
||||
Assert.assertTrue(txhashAsHexString.matches(HEX_REGEX))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user