Scala:如何正确解析 0~FFFF 范围内的十六进制值,确保我总是以 16 位结束,因为每一位都有自己的价值?
Scala: how to parse Hexadecimal value in range 0~FFFF correctly, making sure I always end up with 16 bits, as each bit brings value on its own?
我需要解码包含十六进制值的字符串。
十六进制值需要解码为16位,每一位都有自己的含义。
我尝试使用以下代码,但它是错误的,一旦十六进制值被解码,似乎并不总是 16 位。
我花了很多时间试图解决这个问题,但没能成功,如果有人能帮助我,我将不胜感激。
谢谢!
Here are some Hex examples:
A42
800
242
0
2
4000
> val stat = BigInt(hexVal, 16).toString(2)
> for (s <- stat.indices) {
> s match {
> case 0 => bit1 = stat.substring(s, s+1)
> case 1 => bit2 = stat.substring(s, s+1)
> case 2 => bit3 = stat.substring(s, s+1)
> case 3 => bit4 = stat.substring(s, s+1)
> case 4 => bit5 = stat.substring(s, s+1)
> case 5 => bit6 = stat.substring(s, s+1)
> case 6 => bit7 = stat.substring(s, s+1)
> case 7 => bit8 = stat.substring(s, s+1)
> case 8 => bit9 = stat.substring(s, s+1)
> case 9 => bit10 = stat.substring(s, s+1)
> case 10 => bit11 = stat.substring(s, s+1)
> case 11 => bit12 = stat.substring(s, s+1)
> case 12 => bit13 = stat.substring(s, s+1)
> case 13 => bit14 = stat.substring(s, s+1)
> case 14 => bit15 = stat.substring(s, s+1)
> case 15 => bit16 = stat.substring(s, s+1)
> }
您可以在剩余的缺失数字前加上零以获得完整的 16 位数字。
val bit = BigInt(hexVal, 16).toString(2)
val result = "0" * (16 -bit.length()) + bit
一种选择是使用 f
格式的字符串插值:
val v = BigInt(BigInt(hexVal, 16).toString(2), 10)
val stat = f"$v%016d"
请不要在未检查 hexVal
字符串长度的情况下使用 BigInt
解析不受信任的输入。因为即使是 16 进制,它也具有 O(n^2)
的复杂性,并且可以使您的系统容易受到 DoS/DoW 攻击。
Bellow 是将十六进制字符串解析为 Short
(16 位)值的代码。它对任何输入都能高效安全地工作:
$ scala
Welcome to Scala 2.13.0 (OpenJDK 64-Bit Server VM, Java 1.8.0_222).
Type in expressions for evaluation. Or try :help.
scala> :paste
// Entering paste mode (ctrl-D to finish)
def hexStringToShort(s: String): Short =
if (s.length > 4) sys.error(s"too long hex string: $s")
else {
var v = 0
var i = 0
while (i < s.length) {
v = (v << 4) + hexCharToNibble(s.charAt(i))
i += 1
}
v.toShort
}
def hexCharToNibble(ch: Char): Int =
if (ch >= '0' && ch <= '9') ch - 48
else {
val b = ch & -33
if (b >= 'A' && b <= 'F') b - 55
else sys.error(s"illegal hex char: $ch")
}
// Exiting paste mode, now interpreting.
hexStringToShort: (s: String)Short
hexCharToNibble: (ch: Char)Int
scala> hexStringToShort("A42")
res0: Short = 2626
scala> hexStringToShort("A42").toHexString
res1: String = a42
scala> hexStringToShort("4000").toHexString
res2: String = 4000
要测试位,您可以使用以下函数:
scala> def hasBit(v: Short, b: Int): Boolean = b < 16 && b >= 0 && (v & (1 << b)) != 0
hasBit: (v: Short, b: Int)Boolean
scala> hasBit(hexStringToShort("4000"), 2)
res3: Boolean = false
scala> hasBit(hexStringToShort("4000"), 14)
res4: Boolean = true
scala> hasBit(hexStringToShort("4000"), 15)
res5: Boolean = false
我需要解码包含十六进制值的字符串。
十六进制值需要解码为16位,每一位都有自己的含义。
我尝试使用以下代码,但它是错误的,一旦十六进制值被解码,似乎并不总是 16 位。
我花了很多时间试图解决这个问题,但没能成功,如果有人能帮助我,我将不胜感激。
谢谢!
Here are some Hex examples:
A42
800
242
0
2
4000
> val stat = BigInt(hexVal, 16).toString(2)
> for (s <- stat.indices) {
> s match {
> case 0 => bit1 = stat.substring(s, s+1)
> case 1 => bit2 = stat.substring(s, s+1)
> case 2 => bit3 = stat.substring(s, s+1)
> case 3 => bit4 = stat.substring(s, s+1)
> case 4 => bit5 = stat.substring(s, s+1)
> case 5 => bit6 = stat.substring(s, s+1)
> case 6 => bit7 = stat.substring(s, s+1)
> case 7 => bit8 = stat.substring(s, s+1)
> case 8 => bit9 = stat.substring(s, s+1)
> case 9 => bit10 = stat.substring(s, s+1)
> case 10 => bit11 = stat.substring(s, s+1)
> case 11 => bit12 = stat.substring(s, s+1)
> case 12 => bit13 = stat.substring(s, s+1)
> case 13 => bit14 = stat.substring(s, s+1)
> case 14 => bit15 = stat.substring(s, s+1)
> case 15 => bit16 = stat.substring(s, s+1)
> }
您可以在剩余的缺失数字前加上零以获得完整的 16 位数字。
val bit = BigInt(hexVal, 16).toString(2)
val result = "0" * (16 -bit.length()) + bit
一种选择是使用 f
格式的字符串插值:
val v = BigInt(BigInt(hexVal, 16).toString(2), 10)
val stat = f"$v%016d"
请不要在未检查 hexVal
字符串长度的情况下使用 BigInt
解析不受信任的输入。因为即使是 16 进制,它也具有 O(n^2)
的复杂性,并且可以使您的系统容易受到 DoS/DoW 攻击。
Bellow 是将十六进制字符串解析为 Short
(16 位)值的代码。它对任何输入都能高效安全地工作:
$ scala
Welcome to Scala 2.13.0 (OpenJDK 64-Bit Server VM, Java 1.8.0_222).
Type in expressions for evaluation. Or try :help.
scala> :paste
// Entering paste mode (ctrl-D to finish)
def hexStringToShort(s: String): Short =
if (s.length > 4) sys.error(s"too long hex string: $s")
else {
var v = 0
var i = 0
while (i < s.length) {
v = (v << 4) + hexCharToNibble(s.charAt(i))
i += 1
}
v.toShort
}
def hexCharToNibble(ch: Char): Int =
if (ch >= '0' && ch <= '9') ch - 48
else {
val b = ch & -33
if (b >= 'A' && b <= 'F') b - 55
else sys.error(s"illegal hex char: $ch")
}
// Exiting paste mode, now interpreting.
hexStringToShort: (s: String)Short
hexCharToNibble: (ch: Char)Int
scala> hexStringToShort("A42")
res0: Short = 2626
scala> hexStringToShort("A42").toHexString
res1: String = a42
scala> hexStringToShort("4000").toHexString
res2: String = 4000
要测试位,您可以使用以下函数:
scala> def hasBit(v: Short, b: Int): Boolean = b < 16 && b >= 0 && (v & (1 << b)) != 0
hasBit: (v: Short, b: Int)Boolean
scala> hasBit(hexStringToShort("4000"), 2)
res3: Boolean = false
scala> hasBit(hexStringToShort("4000"), 14)
res4: Boolean = true
scala> hasBit(hexStringToShort("4000"), 15)
res5: Boolean = false