扫描时屏蔽文本 - C.

时间:2015-05-14 20:47:07

标签: c

我必须提示用户输入密码,所以在输入密码时我希望屏蔽字符,我创建了这个代码,其中字符被屏蔽,直到按下回车键。但是字符数组pwd并没有读出我猜的字符!

char pwd[10];
while(ch!=13)
{
     pwd[i] = ch;
     ch = '*' ;
     printf("%c",ch);
     ch=getch();
     i++;
}
pwd[i]='\0';
printf("%s",pwd);

当我尝试打印pwd时没有打印。

2 个答案:

答案 0 :(得分:1)

#define MAX_PW_LENGTH 12

char pwd[MAX_PW_LENGTH + 1];

/** Get Password
 *
 *  \return True on success, false on failure (EOF, too long).
 */
bool getPwd(void)
{
    size_t idx;
    char ch;
    for ( idx = 0 ; idx < sizeof(pwd) - 1 ; idx++ ) {
        ch = getchar();
        if ( (ch == EOF) || (ch == '\n') || (ch == '\r') )
            break;
        pwd[i] = ch;
    }
    pwd[i] = `\0`;
    return (ch == `\r`) || (ch == '\n');  // might depend on OS what return-key yields
}

注意我使用getchar因为getch是非标准的而且(IIRC)不等待输入,但是立即返回(非阻塞)。哦,我实际上没有输出任何内容,因为getchar需要先输入整行(缓冲 - 见下文)。问题是:控制台将chars作为默认键入的回声(也见:见下文)。所以,你需要非回声输入;其余的都会好起来的。

好的,我试图提供一个简单的解决方案。但是,对于Linux至少,getchar()默认有两个主要缺点:默认情况下终端回显所有输入,因此输入时会显示密码。其次,它在输入行之前缓冲输入行,然后在getchar()中返回char-by-char。

第一个显然是一个杀手反物质,而第二个只禁止回响星星或类似物(我不鼓励这样做)。但是,可以使用termios禁用控制台的两个功能;只是谷歌这个。

另一种方法是使用ncurses,它提供了getch()和一个简单的noecho()&#39;调用禁用此行为(和cbreak()禁用缓冲)。但是,这似乎需要使用TUI功能,并且不能像普通的控制台输入那样使用(但仍然比termios更简单)。

结论:使用系统功能获取密码/验证。好像还不知道这个: - )

这是一个ncurses版本:

#include <ncurses.h>

bool getPwd(void)
{
    // this should be done in main() or so only once
      initscr(); noecho(); cbreak();

    size_t idx;
    char ch;
    for ( idx = 0 ; idx < sizeof(pwd) - 1 ; idx++ ) {

        // wait for input
        while ( ERR == (ch = getch()) )  ;
        if ( ch == '\n' )
            break;
              addch('*');     // this should actually be disabled
        pwd[i] = ch;
    }
    pwd[i] = `\0`;
    return ch == '\n';  // might depend on OS what return-key yields
}
}

案件结案。

答案 1 :(得分:0)

作为@Olaf和@EugeneSh。提到,这是一种可怕的密码方式。也就是说,这里有一些帮助。

假设我正在某处初始化,请移动&#34; pwd [i] = ch&#34;到你的循环结束但在&#34; i ++&#34;之前 整个事情看起来应该是这样的(请注意,这仍然是非常错误的):

char pwd[10];
while(ch!=13)
{
     ch = '*' ;
     printf("%c",ch);
     ch=getch();
     pwd[i] = ch;
     i++;
}
pwd[i]='\0';
printf("%s",pwd);

我实际上可能会打印&#34; *&#34;只有在用户输入他们的角色后。让我们解决其他问题。

int i = 0;    /* Since you didn't specify if this was initialized */
char pwd[15]; /* Setting this to 10 would have caused you to overrun your
                buffer.  Not only is that crashy, it's a also a HUGE 
                source of security holes.  Let's not do that. */
/* Unless you're waiting for a user to enter in a 
   character which happens to be ASCII 13, you'll 
   never get out.  Let's just change that to i since 
   I'm guessing you want a 13 character password. */
while(i != 13)  
{
     char ch=getch();
     pwd[i++] = ch; /* You can post increment right here so you don't 
                     have to do it at the end of the loop where you 
                     might forget */
     printf("*");
     fflush(stdout);  /* Since we are using printf to a stdout (not 
                         stderr, we need to manually flush stdout or 
                         things won't show up until a newline is 
                         eventually printed. */
}
printf("\n"); /* Print a newline so we don't end up printing the 
                 password on the same line */

pwd[14]='\0';
printf("Password entered into our crappy security system: %s",pwd);