io.taig.taigless.hashing.Hex.scala Maven / Gradle / Ivy
package io.taig.taigless.hashing
import cats.syntax.all._
/** @see https://www.baeldung.com/java-byte-arrays-hex-strings */
object Hex {
def fromByte(value: Byte): String = {
val digits = new Array[Char](2)
digits(0) = Character.forDigit((value >> 4) & 0xf, 16)
digits(1) = Character.forDigit(value & 0xf, 16)
new String(digits)
}
def toByte(hex: String): Option[Byte] = Some(hex).filter(_.length == 2).flatMap { hex =>
(toDigit(hex.charAt(0)), toDigit(hex.charAt(1))).mapN { (first, second) =>
((first << 4) + second).toByte
}
}
def toDigit(hex: Char): Option[Int] = Some(Character.digit(hex, 16)).filter(_ != -1)
def fromBytes(values: Array[Byte]): String = {
val builder = new StringBuilder()
values.foreach { value =>
builder.append(fromByte(value))
}
builder.result()
}
def toBytes(hex: String): Option[Array[Byte]] =
Some(hex).filter(_.length % 2 == 0).flatMap { hex =>
val bytes = new Array[Byte](hex.length / 2)
var index = 0
var succeeded = true
while (index < hex.length) {
toByte(hex.substring(index, index + 2)) match {
case Some(value) => bytes(index / 2) = value
case None => succeeded = false
}
index += 2
}
Option.when(succeeded)(bytes)
}
}