Этот код использует специфичные для платформы функции и работает как в 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))