Masking password input

ACSolo  发布于4年前 248 阅读 评论(0)

Unix/Linux

Example 1


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <termios.h> #include <unistd.h> #include <stdio.h> #include <iostream> #include <string> using namespace std;int getch() {
    int ch;
    struct termios t_old, t_new;

    tcgetattr(STDIN_FILENO, &t_old);
    t_new = t_old;
    t_new.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &t_new);

    ch = getchar();

    tcsetattr(STDIN_FILENO, TCSANOW, &t_old);
    return ch;
}





string getpass(const char *prompt, bool show_asterisk=true)
{
  const char BACKSPACE=127;
  const char RETURN=10;

  string password;
  unsigned char ch=0;

  cout <<prompt<<endl;

  while((ch=getch())!=RETURN)
    {
       if(ch==BACKSPACE)
         {
            if(password.length()!=0)
              {
                 if(show_asterisk)
                 cout <<"\b \b";
                 password.resize(password.length()-1);
              }
         }
       else          {
             password+=ch;
             if(show_asterisk)
                 cout <<'*';
         }
    }
  cout <<endl;
  return password;
}int main()
{
  const char *correct_password="null";

  string password=getpass("Please enter the password: ",true); // Show asterisks   if(password==correct_password)
      cout <<"Correct password"<<endl;
  else       cout <<"Incorrect password. Try again"<<endl;


  password=getpass("Please enter the password: ",false); // Do not show asterisks   if(password==correct_password)
      cout <<"Correct password"<<endl;
  else       cout <<"Incorrect password. Try again"<<endl;

  return 0;
}


Example 2 - using getpass() function

According to the Linux programmers's manual, this function is obsolete, so avoid it when possible.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstdlib> #include <iostream> using namespace std;const char *mypass="null";int main()
{char *password=getpass("Enter password: ");if(strcmp(password,mypass)==0) cout <<"Correct password!\n";else cout <<"Incorrect password!\n";return 0;
}






Windows

Example 1 - using WinAPI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream> #include <string> #include <windows.h> using namespace std;


string getpass(const char *prompt, bool show_asterisk=true)
{
  const char BACKSPACE=8;
  const char RETURN=13;

  string password;
  unsigned char ch=0;

  cout <<prompt<<endl;

  DWORD con_mode;
  DWORD dwRead;

  HANDLE hIn=GetStdHandle(STD_INPUT_HANDLE);

  GetConsoleMode( hIn, &con_mode );
  SetConsoleMode( hIn, con_mode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT) );

  while(ReadConsoleA( hIn, &ch, 1, &dwRead, NULL) && ch !=RETURN)
    {
       if(ch==BACKSPACE)
         {
            if(password.length()!=0)
              {
                 if(show_asterisk)
                     cout <<"\b \b";
                 password.resize(password.length()-1);
              }
         }
       else          {
             password+=ch;
             if(show_asterisk)
                 cout <<'*';
         }
    }
  cout <<endl;
  return password;
}int main()
{
  const char *correct_password="null";

  cout <<"Test 1: echoing enabled"<<endl;
  string password=getpass("Please enter the password: ",true); // Show asterisks   if(password==correct_password)
      cout <<"Correct password"<<endl;
  else       cout <<"Incorrect password. Try again"<<endl;

  cout <<"\nTest 2: echoing disabled"<<endl;
  password=getpass("Please enter the password: ",false); // Do not show asterisks   if(password==correct_password)
      cout <<"Correct password"<<endl;
  else       cout <<"Incorrect password. Try again"<<endl;

  return 0;
}





Example 2 - using conio.h

This code is analogous to the previous example but uses getch() function from conio.h header to get unbuffered console input. Note that conio.h is a Borland-specific header, so avoid it when possible.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream> #include <string> #include <conio.h> using namespace std;


string getpass(const char *prompt, bool show_asterisk=true)
{
  const char BACKSPACE=8;
  const char RETURN=13;

  string password;
  unsigned char ch=0;

  cout <<prompt<<endl;

  while((ch=getch())!=RETURN)
    {
       if(ch==BACKSPACE)
         {
            if(password.length()!=0)
              {
                 if(show_asterisk)
                 cout <<"\b \b";
                 password.resize(password.length()-1);
              }
         }
       else if(ch==0 || ch==224) // handle escape sequences          {
             getch(); // ignore non printable chars              continue;
         }
       else          {
             password+=ch;
             if(show_asterisk)
                 cout <<'*';
         }
    }
  cout <<endl;
  return password;
}int main()
{
  const char *correct_password="null";

  string password=getpass("Please enter the password: ",true); // Show asterisks   if(password==correct_password)
      cout <<"Correct password"<<endl;
  else       cout <<"Incorrect password. Try again"<<endl;


  password=getpass("Please enter the password: ",false); // Do not show asterisks   if(password==correct_password)
      cout <<"Correct password"<<endl;
  else       cout <<"Incorrect password. Try again"<<endl;

  return 0;
}

Note that if the password is longer that the console width (80 characters) backspace will not delete asterisks from the previous line.





Using curses library

Curses library is one of the best choices for cross-platform console manipulation. Keep in mind that this library has been designed for C programming language, so you won't be able to use C++ iostream's with it.


Example 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <string> #include <curses.h> using namespace std;


string getpass(const char *prompt)
{
  printw(prompt);
  noecho();  // disable character echoing   char buff[64];
  getnstr(buff,sizeof(buff));

  echo(); // enable character echoing again   return buff;
}int main()
{
   const string correct_password="null";

   initscr(); // enable ncurses    string pwd=getpass("Please enter the password: ");

   if(correct_password==pwd)
       printw("\nCorrect password!");
   else        printw("\nIncorrect password. Try again");


    getch(); // Wait for a keypress     endwin(); // disable ncurses     return 0;
}


Example 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <string> #include <curses.h> using namespace std;


string getpass(const char *prompt, bool show_asterisk=true)
{
  const char BACKSPACE=8;
  const char RETURN=10; // Note: 10 for curses, 13 for conio   string password;
  unsigned char ch=0;

  printw(prompt);
  printw("\n");

  noecho(); // Disable echoing   while((ch=getch())!=RETURN)
    {
       if(ch==BACKSPACE)
         {
            if(password.length()!=0)
              {
                 if(show_asterisk)
                 printw("\b \b");
                 password.resize(password.length()-1);
              }
         }
       else if(ch!=27) // ignore 'escape' key          {
             password+=ch;
             if(show_asterisk)
                 printw("*");
         }
    }

  echo();
  printw("\n");
  return password;
}int main()
{
  initscr();

  const char *correct_password="null";

  printw("Test 1: echoing enabled\n");
  string password=getpass("Please enter the password: ",true); // Show asterisks   if(password==correct_password)
      printw("Correct password!\n");
  else       printw("Incorrect password. Try again\n");

  printw("\nTest 2: echoing disabled\n");
  password=getpass("Please enter the password: ",false); // Do not show asterisks   if(password==correct_password)
      printw("Correct password");
  else       printw("Incorrect password. Try again");

  printw("\n\nPress any key to continue...");
  getch();
  endwin();
  return 0;
}

 
 
 
 
Vote: I like it 0 Vote: I do not like it

Reply: Reply it before Login