Scala: как правильно проанализировать шестнадцатеричное значение в диапазоне 0 ~ FFFF, убедившись, что я всегда получаю 16 бит, так как каждый бит приносит значение само по себе? - PullRequest
0 голосов
/ 24 октября 2019

Мне нужно декодировать строку, которая содержит шестнадцатеричное значение.

Шестнадцатеричное значение необходимо декодировать до 16 бит, каждый бит имеет свое значение.

Я пытаюсь использовать следующий код:но это неправильно, и кажется, что не всегда 16 бит, как только значение Hex декодируется.

Я потратил значительное количество времени, пытаясь решить эту проблему, но не смог, поэтому был бы благодарен, если кто-то можетпомоги мне.

Спасибо!

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)
>      }

Ответы [ 3 ]

0 голосов
/ 24 октября 2019

Один из вариантов - использовать интерполяцию строк в формате f:

val v = BigInt(BigInt(hexVal, 16).toString(2), 10)

val stat = f"$v%016d"
0 голосов
/ 24 октября 2019

Пожалуйста, не используйте BigInt для анализа ненадежных входных данных без проверки длины строки hexVal. Потому что даже для базы 16 он имеет сложность O(n^2) и может сделать вашу систему уязвимой для DoS / DoW-атак.

Ниже представлен код, который анализирует шестнадцатеричную строку в значение 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
0 голосов
/ 24 октября 2019

Остальные пропущенные цифры можно добавить к нулю, чтобы получить 16 полных цифр.

val bit = BigInt(hexVal, 16).toString(2)
val result = "0" * (16 -bit.length()) + bit
...