маскировка ввода пароля в терминале Windows на языке C

#c

Вопрос:

Я нахожусь в Windows и попробовал следующий код для маскировки ввода пароля:

 #include <stdio.h>
#include <conio.h>
int main() {
    int i = 0;
    char ch, password[13];
    printf("nEnter Password (Upto 12 chars.): ");
    while (i < 12) {
        ch = getch();
        if (ch == ' ') {
            --i;
        } else if (ch == 'b') {
            printf("b b");
            i -= 2;
        } else if (ch == 'r')
            break;
        else {
            password[i] = ch;
            printf("*");
        }
          i;
    }
    password[i] = '';
    printf("nPassword: %s",password);
    return 0;
}
 

Проблема с приведенным выше кодом заключается в том, что, когда я не ввел никаких символов и нажимаю пробел, печатная строка Enter Password (Upto 12 chars.): стирает свои символы один за другим. Это я смог обойти, сделав это Enter Password (Upto 12 chars.):n , и теперь он не будет удалять свои символы. Но есть еще одна проблема, и это всякий раз, когда я пытаюсь закрыть терминал, нажав Alt F4 два нажатия клавиш, которые считаются вводимыми getch (), и я получаю два возвращенных и отображаемых символа. Я знаю , что это моя вина, так как другая часть занимает все, кроме r , b и пробелов, но я хочу, чтобы мне помогли это исправить.

Что я хочу, так это иметь возможность маскировать ввод пароля без каких — либо из вышеперечисленных проблем. Я уже использовал клиент командной строки MySQL раньше, и он запрашивает ввод пароля просто отлично. Что-нибудь подобное или близкое к этому было бы оценено по достоинству.

Я должен упомянуть, что это для университетского проекта.

Любая помощь будет признательна

Комментарии:

1. Если вы используете неэхо getch() , зачем вам нужно выводить обратные пространства? В любом случае, если вы используете консольный ввод-вывод, используйте cprintf вместо stdout версии printf .

2. Что касается getch() возврата дважды для клавиш функции и перемещения курсора, сделайте небольшую функцию ввода клавиш. Используются два символа «escape». Легко выяснить, какие они. Если один из них получен, найдите другой getch() и обработайте его соответствующим образом. Вы можете преобразовать такие входные данные в int значение > 256.

3. @WeatherVane Я смог найти ASCII-код Esc ключа (27) и смог проигнорировать его, но я не понимаю, что делать дальше. Кроме того, cprintf() не работает

4. Функциональные клавиши и клавиши курсора дают два значения ( 0 или 224 и другое значение), поэтому, если вы хотите игнорировать эти клавиши, когда вы снова получите 0 или 224 позвоните getch() и продолжите. Я не думаю, что вам следует игнорировать клавишу Esc, она была нажата не просто так. Ctrl-C не завершит программу при вводе в консоль.

5. » cprintf() не работает». Это действительно работает, так что ты имеешь в виду?

Ответ №1:

Я исправил свой собственный код. Черпал вдохновение из какого-то старого кода на C (не копируй макароны).

Он игнорирует пробелы, Esc клавиши, функции и клавиши со стрелками, правильно работает с обратным пространством и выходит из цикла при нажатии Tab или Enter . И теперь он не удаляет символы из printf() строки при нажатии на пробел при пустом вводе.

Хитрость заключается в том, чтобы назначать ввод только тогда, когда все остальные if else if условия и не выполняются, и увеличивать счетчик только в этом else блоке. А затем, когда цикл закончится, поместите a '' в последний индекс строки.

Вот код:

 #include <conio.h>
#include <stdio.h>
#define PASSWORD_LENGTH 12
int main() {
    int i = 0;
    char password[PASSWORD_LENGTH   1];
    int ch;
    printf("nEnter Password (Upto 12 chars.): ");
    while (i < PASSWORD_LENGTH) {
        ch = getch();
        if (ch == ' ' || ch == 27) {
            continue;
        } else if (ch == 'b') {
            if (i > 0) {
                printf("b b");
                --i;
            } else {
                continue;
            }
        } else if (ch == 'r' || ch == 't') {
            break;
        } else if (ch == 0 || ch == 224) {
            ch = getch();
            continue;
        } else {
            password[i  ] = ch;
            printf("*");
        }
    }
    password[i] = '';
    printf("n,%s,", password); //this can be removed as it is only for displaying output
    return 0;
}
 

Комментарии:

1. Итак, просто любопытно — как долго вы ждали ответа, прежде чем начали отлаживать его самостоятельно?

2. Я делал это сам, ожидая ответа. Я продолжал обновлять страницу, чтобы найти какие-либо новые ответы или комментарии. Просматривая ответы о маскировке паролей C, я нашел старую запись на форумах msdn, которая вдохновила меня, и я начал работать в этом направлении, и вот я с ответом.