Этот вопрос задан раньше и до сих пор не имеет ответа, насколько я могу судить. Поэтому я снова задаю этот вопрос, чтобы, наконец, получить ответ на этот вопрос. (Если я ошибаюсь, дайте мне URL-адрес ответа.)
Проблема: Программисты хотят, чтобы пользователи вводили пароли. Функция getpass() хороша для этой цели, но ее использование имеет недостаток: при вводе пароля ничего не печатается в стандартный вывод.
Вопрос: Как можно реализовать getpass(), пока звездочки печатаются для каждого символа, введенного пользователем? (Конечно, обратное пространство - и идеально pos1 и конец - следует позаботиться соответственно.)
Мотивация: В сообществе были люди, которые не понимали, почему этот вопрос задан. И затем ссылается на getpass(): a) таким образом игнорируя поставленную задачу и б) не думая о том, что ссылка не ответит на вопрос. Причина, по которой s.o. может потребоваться напечатать звездочки для удобства пользователей: они получают прямой визуальный ответ во время ввода пароля. Поэтому они не путаются, нажимая клавиши и - там глаза - ничего не происходит.
Шаг к решению:
Позвольте мне представить первый шаг к решению здесь. Пожалуйста, помогите, чтобы превратить его в реальное решение.
Существует модуль с именем getch, который, по-видимому, позволяет читать символ по символу из stdin. Backspace - довольно странно - отображается в целочисленное значение 127, но такое решение может выглядеть следующим образом:
def readLineWithAsterisks():
sBuffer = ''
while True:
c = getch.getch()
if c == '\n':
return sBuffer
elif ord(c) == 127:
if len(sBuffer) > 0:
sys.stdout.write('\x08 \x08')
sys.stdout.flush()
sBuffer = sBuffer[0:-1]
continue
else:
sys.stdout.write('*')
sys.stdout.flush()
sBuffer += c
Но этот код имеет некоторые недостатки. Сначала я очень смущен тем, что c не был '\ b', если s.o. вступил в обратное пространство. Может быть и так. есть объяснение для этого? Во-вторых обрабатываются только ASCII-символы, по крайней мере, в Linux. Я не знаю о Windows здесь, но если нажимается символ, отличный от A-Z0-9, строка c = getch.getch() выдает исключение. Кажется, что getch() не может обрабатывать умлауты и другие типы символов, по крайней мере до некоторой степени.
Чтобы прийти к решению, необходимо решить следующие проблемы:
- Как можно считывать из stdin символ по символу в отношении символов, отличных от ASCII?
- Как это можно сделать независимым от платформы способом?
- Как это можно сделать безопасно (без проблем безопасности)? (getpass как-то, кажется, обращается к этому, но я не совсем понимаю, как.)
Возможно, об этом никто не знает. Насколько мне известно, такие вопросы, которые были заданы ранее, остались без ответа. Но, может быть, в сообществе есть несколько разработчиков программного обеспечения, которые знают больше обо всем этом и могут помочь здесь? При успехе я могу получить решение, предоставленное на GitHub в качестве модуля python.