mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-08 21:04:20 +00:00
Add string-to-hex and back conversions
Add parseHexStr and toHex and tests.
This commit is contained in:
@@ -930,6 +930,19 @@ proc toHex*[T](x: T): string =
|
||||
## Shortcut for ``toHex(x, T.sizeOf * 2)``
|
||||
toHex(BiggestInt(x), T.sizeOf * 2)
|
||||
|
||||
proc toHex*(s: string): string {.noSideEffect, rtl.} =
|
||||
## Converts a bytes string to its hexadecimal representation.
|
||||
##
|
||||
## The output is twice the input long. No prefix like
|
||||
## ``0x`` is generated.
|
||||
const HexChars = "0123456789ABCDEF"
|
||||
result = newString(s.len * 2)
|
||||
for pos, c in s:
|
||||
var n = ord(c)
|
||||
result[pos * 2 + 1] = HexChars[n and 0xF]
|
||||
n = n shr 4
|
||||
result[pos * 2] = HexChars[n]
|
||||
|
||||
proc intToStr*(x: int, minchars: Positive = 1): string {.noSideEffect,
|
||||
rtl, extern: "nsuIntToStr".} =
|
||||
## Converts `x` to its decimal representation.
|
||||
@@ -1012,6 +1025,43 @@ proc parseHexInt*(s: string): int {.noSideEffect, procvar,
|
||||
of '\0': break
|
||||
else: raise newException(ValueError, "invalid integer: " & s)
|
||||
|
||||
proc generateHexCharToValueMap(): string =
|
||||
## Generate a string to map a hex digit to uint value
|
||||
result = ""
|
||||
for inp in 0..255:
|
||||
let ch = chr(inp)
|
||||
let o =
|
||||
case ch:
|
||||
of '0'..'9': inp - ord('0')
|
||||
of 'a'..'f': inp - ord('a') + 10
|
||||
of 'A'..'F': inp - ord('A') + 10
|
||||
else: 17 # indicates an invalid hex char
|
||||
result.add chr(o)
|
||||
|
||||
const hexCharToValueMap = generateHexCharToValueMap()
|
||||
|
||||
proc parseHexStr*(s: string): string {.noSideEffect, procvar,
|
||||
rtl, extern: "nsuParseHexStr".} =
|
||||
## Convert hex-encoded string to byte string, e.g.:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
## hexToStr("00ff") == "\0\255"
|
||||
##
|
||||
## Raises ``ValueError`` for an invalid hex values. The comparison is
|
||||
## case-insensitive.
|
||||
if s.len mod 2 != 0:
|
||||
raise newException(ValueError, "Incorrect hex string len")
|
||||
result = newString(s.len div 2)
|
||||
var buf = 0
|
||||
for pos, c in s:
|
||||
let val = hexCharToValueMap[ord(c)].ord
|
||||
if val == 17:
|
||||
raise newException(ValueError, "Invalid hex char " & repr(c))
|
||||
if pos mod 2 == 0:
|
||||
buf = val
|
||||
else:
|
||||
result[pos div 2] = chr(val + buf shl 4)
|
||||
|
||||
proc parseBool*(s: string): bool =
|
||||
## Parses a value into a `bool`.
|
||||
##
|
||||
|
||||
Reference in New Issue
Block a user