Thanks for @LeFF to discovering that thread, with it the code becomes: 
    
    
    import macros
    type
      estring = distinct string
    
    proc `xor`*(x, y: char): char {.magic: "BitxorI", noSideEffect.}
    
    proc fnv32a*[T: 
string|openArray[char]|openArray[uint8]|openArray[int8]](data: T): int32 =
      result = -18652613'i32
      for b in items(data):
        result = result xor int32(ord(b))
        result = result *% 16777619
    
    proc decodeStr*(s: estring, key: int32): string =
      var s = string(s)
      var k = key
      result = newString(s.len)
      for i in s.low .. s.high:
        result[i] = s[i]
        result[i] = result[i] xor chr(uint8(k and 0xFF))
        result[i] = result[i] xor chr(uint8((k shr 8) and 0xFF))
        result[i] = result[i] xor chr(uint8((k shr 16) and 0xFF))
        result[i] = result[i] xor chr(uint8((k shr 24) and 0xFF))
        k = k +% 1
    
    proc encodeStr*(s: string, key: int32): estring = 
estring(decodeStr(estring(s), key))
    
    var encodedCounter {.compiletime.}: int32 = fnv32a(CompileTime & 
CompileDate) and 0x7FFFFFFF
    
    # term rewriting macro
    macro encrypt*{s}(s: string{lit}): untyped =
      var encodedStr = encodeStr($s, encodedCounter)
      result = quote do:
        decodeStr(estring(`encodedStr`), `encodedCounter`)
      encodedCounter = (encodedCounter *% 16777619) and 0x7FFFFFFF
    
    # test-case
    echo "hello"
    
    
    Run

Or you could even import this code from other modules and all string literals 
in them will automatically get encrypted :)

Reply via email to