Ok this is embarrassing but what's Nim's equivalent of printf? In particular stringifying a bunch of bytes as a hex string? I see a format proc in strutils but it seems to only accept string varargs. I was trying to put together a crude guid generation function I have in Golang (see below) but I'm stumped.
func guid() string{
f, _ := os.Open("/dev/urandom", os.O_RDONLY, 0)
b := make([]byte, 16)
f.Read(b)
f.Close()
uuid := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
return uuid
}
proc guid():string=
let f = open("/dev/urandom")
var b:array[16, byte]
discard readBytes(f, b, 0, 16)
close(f)
format("%x-%x-%x-%x-%x", b[0..4], b[4..6], b[6..8], b[8..10], b[10..15])
I understand I can use sprintf directly from C but don't know what function signature to use!
Thanks for any help!
Have a look at toHex() in strutils which for anything bigger than a byte, you can specify the number of Hex chars to produce, and for a byte will output two hex chars.
so maybe as the equivalent of one of your %x try (untested)
"$1$2$3$4" % [toHex(b[0]), toHex(b[1]), toHex(b[2]), toHex(b[3])]
and not sure what the byte order should be :-(import strutils
proc hexDump*[T](v: T): string =
var s: seq[uint8] = @[]
s.setLen(v.sizeof)
copymem(addr(s[0]), v.unsafeAddr, v.sizeof)
result = ""
for i in s: result.add(i.toHex)
var
i: int64 = 123
ui: uint64 = 123
f: float = 123.45
s = @[1, 2, 3, 4]
t: tuple[a: int, b: string] = (1, "123")
set: set[uint8] = {1'u8..3'u8, 5'u8..6'u8}
a: array[5, uint8] = [1'u8, 2, 3, 4, 5]
echo i.hexDump
echo ui.hexDump
echo f.hexDump
echo s.hexDump
echo t.hexDump
echo set.hexDump
echo a.hexDump
Without copying:
import strutils
proc hexDump*[T](v: T): string =
template read_u8(p: ByteAddress): untyped =
(cast[ptr uint8](p)[])
var p = cast[ByteAddress](v.unsafeAddr)
let e = p + v.sizeof
result = ""
while p < e:
result.add(read_u8(p).toHex)
p.inc
var
i: int64 = 123
ui: uint64 = 123
f: float = 123.45
s = @[1, 2, 3, 4]
t: tuple[a: int, b: string] = (1, "123")
set: set[uint8] = {1'u8..3'u8, 5'u8..6'u8}
a: array[5, uint8] = [1'u8, 2, 3, 4, 5]
echo i.hexDump
echo ui.hexDump
echo f.hexDump
echo s.hexDump
echo t.hexDump
echo set.hexDump
echo a.hexDump
Thanks @jlp765 and @dataman. I decided to go with the following for now.
import strutils
proc guid():string=
result = ""
const n = 8
let f = open("/dev/urandom")
var a:array[n, byte]
discard readBytes(f, a, 0, n)
close(f)
for b in a: result.add(toHex(b))
But I must admit, I'm rather surprised a C style sprintf or Lisp style format is missing (at least I couldn't find it so far) in Nim's stdlib. I'm just a beginner in Nim otherwise I'd write one myself. Perhaps hopefully soon.