在lua中隐藏带星号的密码

时间:2011-04-26 08:30:25

标签: lua

我有办法在lua中提问密码但是用星号隐藏吗?

我在问一个控制台应用程序

2 个答案:

答案 0 :(得分:5)

对于Unix:使用os.execute("stty -echo raw")关闭回显并进入原始模式(逐个字符输入)和os.execute("stty echo cooked")将其打开并在完成后退出原始模式。在原始模式下,您可以使用io.stdin:read(1)获取输入的每个字符并随时回显星号(使用io.flush确保字符立即显示)。您需要自己处理删除和行​​尾。

对于Windows,情况有点棘手。查看What would be the Windows batch equivalent for HTML's input type=“password”?的某些方法,其中最好的方法似乎是VB脚本。

后记

感谢lhf指出除了输入-echo之外还需要原始模式,并在每个输出星号后刷新以获得所需的结果:除非你有两个,否则直到该行结束时才会回显星号

答案 1 :(得分:2)

此代码使用特定于平台的功能,适用于Linux和32位Windows 兼容Lua 5.1和Lua 5.2

local console

local function enter_password(prompt_message, asterisk_char, max_length)
   -- returns password string
   -- "Enter" key finishes the password
   -- "Backspace" key undoes last entered character
   if not console then
      if (os.getenv'os' or ''):lower():find'windows' then
         ------------------ Windows ------------------
         local shift = 10
         -- Create executable file which returns (getch()+shift) as exit code
         local getch_filespec = 'getch.com'
         -- mov AH,8
         -- int 21h
         -- add AL,shift
         -- mov AH,4Ch
         -- int 21h
         local file = assert(io.open(getch_filespec, 'wb'))
         file:write(string.char(0xB4,8,0xCD,0x21,4,shift,0xB4,0x4C,0xCD,0x21))
         file:close()
         console = {
            wait_key = function()
               local code_Lua51, _, code_Lua52 = os.execute(getch_filespec)
               local code = (code_Lua52 or code_Lua51) - shift
               assert(code >= 0, getch_filespec..' execution failed')
               return string.char(code)
            end,
            on_start = function() end,
            on_finish = function() end,
            backspace_key = '\b'
         }
         -------------------------------------------
      else
         ------------------ Linux ------------------
         console = {
            wait_key = function()
               return io.read(1)
            end,
            on_start = function()
               os.execute'stty -echo raw'
            end,
            on_finish = function()
               os.execute'stty sane'
            end,
            backspace_key = '\127'
         }
         -------------------------------------------
      end
   end
   io.write(prompt_message or '')
   io.flush()
   local pwd = ''
   console.on_start()
   repeat
      local c = console.wait_key()
      if c == console.backspace_key then
         if #pwd > 0 then
            io.write'\b \b'
            pwd = pwd:sub(1, -2)
         end
      elseif c ~= '\r' and #pwd < (max_length or 32) then
         io.write(asterisk_char or '*')
         pwd = pwd..c
      end
      io.flush()
   until c == '\r'
   console.on_finish()
   io.write'\n'
   io.flush()
   return pwd
end

-- Usage example
local pwd = enter_password'Enter password: '
print('You entered: '..pwd:gsub('%c','?'))
print(pwd:byte(1,-1))