httpserver-b64decode.lua 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #!/usr/local/bin/lua
  2. -- httpserver-b64decode.lua
  3. -- Part of nodemcu-httpserver, contains b64 decoding used for HTTP Basic Authentication.
  4. -- Based on http://lua-users.org/wiki/BaseSixtyFour by Alex Kloss
  5. -- compatible with lua 5.1
  6. -- http://www.it-rfc.de
  7. -- Author: Marcos Kirsch
  8. -- bitshift functions (<<, >> equivalent)
  9. -- shift left
  10. local function lsh(value,shift)
  11. return (value*(2^shift)) % 256
  12. end
  13. -- shift right
  14. local function rsh(value,shift)
  15. -- Lua builds with no floating point don't define math.
  16. if math then return math.floor(value/2^shift) % 256 end
  17. return (value/2^shift) % 256
  18. end
  19. -- return single bit (for OR)
  20. local function bit(x,b)
  21. return (x % 2^b - x % 2^(b-1) > 0)
  22. end
  23. -- logic OR for number values
  24. local function lor(x,y)
  25. result = 0
  26. for p=1,8 do result = result + (((bit(x,p) or bit(y,p)) == true) and 2^(p-1) or 0) end
  27. return result
  28. end
  29. -- Character decoding table
  30. local function toBase64Byte(char)
  31. ascii = string.byte(char, 1)
  32. if ascii >= string.byte('A', 1) and ascii <= string.byte('Z', 1) then return ascii - string.byte('A', 1)
  33. elseif ascii >= string.byte('a', 1) and ascii <= string.byte('z', 1) then return ascii - string.byte('a', 1) + 26
  34. elseif ascii >= string.byte('0', 1) and ascii <= string.byte('9', 1) then return ascii + 4
  35. elseif ascii == string.byte('-', 1) then return 62
  36. elseif ascii == string.byte('_', 1) then return 63
  37. elseif ascii == string.byte('=', 1) then return nil
  38. else return nil, "ERROR! Char is invalid for Base64 encoding: "..char end
  39. end
  40. -- decode base64 input to string
  41. return function(data)
  42. local chars = {}
  43. local result=""
  44. for dpos=0,string.len(data)-1,4 do
  45. for char=1,4 do chars[char] = toBase64Byte((string.sub(data,(dpos+char),(dpos+char)) or "=")) end
  46. result = string.format(
  47. '%s%s%s%s',
  48. result,
  49. string.char(lor(lsh(chars[1],2), rsh(chars[2],4))),
  50. (chars[3] ~= nil) and string.char(lor(lsh(chars[2],4),
  51. rsh(chars[3],2))) or "",
  52. (chars[4] ~= nil) and string.char(lor(lsh(chars[3],6) % 192,
  53. (chars[4]))) or ""
  54. )
  55. end
  56. return result
  57. end