Scala十六进制字符串到字节

nvbavucw  于 2022-11-09  发布在  Scala
关注(0)|答案(4)|浏览(272)

在Scala中,有没有一种巧妙的方法可以将十六进制编码的String转换为协议buf ByteString(然后再转换回来)?

b09cbbtk

b09cbbtk1#

您可以(无需其他依赖项)将DatatypeConverter用作:

import com.google.protobuf.ByteString
import javax.xml.bind.DatatypeConverter
val hexString: String = "87C2D268483583714CD5"
val byteString: ByteString = ByteString.copyFrom(
  DatatypeConverter.parseHexBinary(hexString)
)
val originalString = DatatypeConverter.printHexBinary(byteString.toByteArray)
xbp102n0

xbp102n02#

您可以使用java.math.BigInteger来解析String,获得Array[Byte],然后将其转换为ByteString。这将是第一步:

import java.math.BigInteger

val s = "f263575e7b00a977a8e9a37e08b9c215feb9bfb2f992b2b8f11e"

val bs = new BigInteger(s, 16).toByteArray

bs的内容现在为:

Array(0, -14, 99, 87, 94, 123, 0, -87, 119, -88, -23, -93, 126, 8, -71, -62, 21, -2, -71, -65, -78, -7, -110, -78, -72, -15, 30)

然后,您可以使用(例如)copyFrom方法(这里是JavaDoc)将其转换为ByteString

zbdgwd5y

zbdgwd5y3#

因为问题的标题没有提到Protobuf,所以如果任何人正在寻找一种将十六进制字符串转换为任意大小数组的Seq[Byte]而不需要任何依赖关系的解决方案:(不要忘记根据需要添加输入验证)

val zeroChar: Byte = '0'.toByte
val aChar: Byte = 'a'.toByte

def toHex(bytes: Seq[Byte]): String = bytes.map(b => f"$b%02x").mkString

def toBytes(hex: String): Seq[Byte] = {

  val lowerHex = hex.toLowerCase

  val (result: Array[Byte], startOffset: Int) =
    if (lowerHex.length % 2 == 1) {

    // Odd
    val r = new Array[Byte]((lowerHex.length >> 1) + 1)
    r(0) = toNum(lowerHex(0))
    (r, 1)

  } else {

    // Even
    (new Array[Byte](lowerHex.length >> 1), 0)
  }

  var inputIndex = startOffset
  var outputIndex = startOffset
  while (outputIndex < result.length) {

    val byteValue = (toNum(lowerHex(inputIndex)) * 16) +
      toNum(lowerHex(inputIndex + 1))

    result(outputIndex) = byteValue.toByte

    inputIndex += 2
    outputIndex += 1
  }

  result
}

def toNum(lowerHexChar: Char): Byte =
  (if (lowerHexChar < 'a') lowerHexChar.toByte - zeroChar else 10 +
    lowerHexChar.toByte - aChar).toByte

https://scalafiddle.io/sf/PZPHBlT/2

8fsztsew

8fsztsew4#

从Java 17开始可以使用标准接口将十六进制字符串解析为字节数组。

import java.util.HexFormat

HexFormat.of.parseHex("d719af")

相关问题