Last active
October 5, 2015 07:40
-
-
Save goldobin/0ced40efe7d37a264ffc to your computer and use it in GitHub Desktop.
Hex Codec for Scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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