text.lua 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. -- Text processing functions.
  2. local M = {}
  3. local alphabet = '0123456789ABCDEF'
  4. local atoi = {} ---@type table<string, integer>
  5. local itoa = {} ---@type table<integer, string>
  6. do
  7. for i = 1, #alphabet do
  8. local char = alphabet:sub(i, i)
  9. itoa[i - 1] = char
  10. atoi[char] = i - 1
  11. atoi[char:lower()] = i - 1
  12. end
  13. end
  14. --- Hex encode a string.
  15. ---
  16. --- @param str string String to encode
  17. --- @return string : Hex encoded string
  18. function M.hexencode(str)
  19. local enc = {} ---@type string[]
  20. for i = 1, #str do
  21. local byte = str:byte(i)
  22. enc[2 * i - 1] = itoa[math.floor(byte / 16)]
  23. enc[2 * i] = itoa[byte % 16]
  24. end
  25. return table.concat(enc)
  26. end
  27. --- Hex decode a string.
  28. ---
  29. --- @param enc string String to decode
  30. --- @return string? : Decoded string
  31. --- @return string? : Error message, if any
  32. function M.hexdecode(enc)
  33. if #enc % 2 ~= 0 then
  34. return nil, 'string must have an even number of hex characters'
  35. end
  36. local str = {} ---@type string[]
  37. for i = 1, #enc, 2 do
  38. local u = atoi[enc:sub(i, i)]
  39. local l = atoi[enc:sub(i + 1, i + 1)]
  40. if not u or not l then
  41. return nil, 'string must contain only hex characters'
  42. end
  43. str[(i + 1) / 2] = string.char(u * 16 + l)
  44. end
  45. return table.concat(str), nil
  46. end
  47. return M