Published by
Nov 7, 2009 (last update: Jan 29, 2012)

Masking password input

Score: 3.8/5 (109 votes)
*****

Contents



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;
}


Notes:
1. Download curses here:
http://www.pickinpatchfarm.com/projects/pdcurses/files/
2. You must link your project with pdcurses.lib library.
  • 1793521592 2018-02-23
  • 2864591591 2018-02-23
  • 6167231590 2018-02-23
  • 3669201589 2018-02-23
  • 7946381588 2018-02-23
  • 8957701587 2018-02-23
  • 3891941586 2018-02-23
  • 6039851585 2018-02-23
  • 2573991584 2018-02-23
  • 7728781583 2018-02-23
  • 3731582 2018-02-23
  • 1007451581 2018-02-22
  • 8908121580 2018-02-22
  • 141161579 2018-02-22
  • 9421578 2018-02-22
  • 2826901577 2018-02-22
  • 3647361576 2018-02-22
  • 5717551575 2018-02-22
  • 523811574 2018-02-22
  • 6439871573 2018-02-22