Skip to content

Instantly share code, notes, and snippets.

@goldobin
Last active October 5, 2015 07:40
Show Gist options
  • Save goldobin/0ced40efe7d37a264ffc to your computer and use it in GitHub Desktop.
Save goldobin/0ced40efe7d37a264ffc to your computer and use it in GitHub Desktop.
Hex Codec for Scala
object HexCodecs {
private def parseHexChar(c: Char): Int = {
val b =
if (c >= '0' && c <= '9')
c - '0'
else if (c >= 'a' && c <= 'f')
(c - 'a') + 10
else if (c >= 'A' && c <= 'F')
(c - 'A') + 10
else
throw new RuntimeException("Invalid hex character: '" + c + "'.")
b
}
private def parseHexString(hex: String): ByteString = {
require((hex.length & 1) == 0, "Hex string must have length 2n.")
val array = new Array[Byte](hex.length >> 1)
for (i <- 0 until hex.length by 2) {
val c1 = hex.charAt(i)
val c2 = hex.charAt(i + 1)
array(i >> 1) = ((parseHexChar(c1) << 4) | parseHexChar(c2)).asInstanceOf[Byte]
}
ByteString(array)
}
private def convertToHexChar(b: Byte): Char = {
require(b >= 0 && b <= 15, "Byte " + b + " was not between 0 and 15")
if (b < 10)
('0'.asInstanceOf[Int] + b).asInstanceOf[Char]
else
('a'.asInstanceOf[Int] + (b - 10)).asInstanceOf[Char]
}
private def convertToHexString(bs: IndexedSeq[Byte]): String = {
val builder = new mutable.StringBuilder(bs.length * 2)
for (i <- 0 until bs.length) {
val b = bs(i)
val bi: Int = if (b < 0) b + 256 else b
builder append convertToHexChar((bi >>> 4).asInstanceOf[Byte])
builder append convertToHexChar((bi & 0x0F).asInstanceOf[Byte])
}
builder.toString()
}
implicit class IndexedSeqWithHexMethods(bs: IndexedSeq[Byte]) {
def encodeHex: String = convertToHexString(bs)
}
implicit class ByteWithHexMethods(b: Byte) {
def encodeHex: String = convertToHexString(IndexedSeq(b))
}
implicit class StringWithToHexString(s: String) {
import ByteStringConverters._
def encodeHex: String = convertToHexString(s.toByteString)
def decodeHex: ByteString = parseHexString(s)
def decodeHexStripWhitespaces: ByteString = parseHexString(s.replaceAll("\\s+", ""))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment