簡體   English   中英

C命令行密碼輸入

[英]C command-line password input

我想允許用戶使用命令行界面輸入密碼。 但我不想在屏幕上顯示此密碼(或顯示“ ****”)。

用C怎么做? 謝謝。

更新:

我僅在Linux上工作。 因此,我實際上並不關心Win或其他系統。 我嘗試了盧卡斯的解決方案,效果很好。 但是,我還有另一個問題:

  1. 如果這是一個單進程和單線程應用程序,那么更改termios的設置會影響不同的終端嗎?

  2. 1個進程-多線程,多進程-多線程怎么樣?

非常感謝。

如果您的系統提供了它,則可以使用getpass

#include <unistd.h>
/* ... */
char *password = getpass("Password: ");

鍵入字符后,將不會顯示任何內容。

如果使用的是UNIX環境,則可能會關閉命令行的ECHO。

#include <stdio.h>
#include <termios.h>
#include <unistd.h>   

#define SIZE 100

void getPassword(char password[])
{
    static struct termios oldt, newt;
    int i = 0;
    int c;

    /*saving the old settings of STDIN_FILENO and copy settings for resetting*/
    tcgetattr( STDIN_FILENO, &oldt);
    newt = oldt;

    /*setting the approriate bit in the termios struct*/
    newt.c_lflag &= ~(ECHO);          

    /*setting the new bits*/
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    /*reading the password from the console*/
    while ((c = getchar())!= '\n' && c != EOF && i < SIZE){
        password[i++] = c;
    }
    password[i] = '\0';

    /*resetting our old STDIN_FILENO*/ 
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);

}


int main(void)
{
    char password[SIZE];
    printf("please enter password\n");
    getPassword(password);

    printf("Do something with the password <<%s>>\n", password);
    return 0;
}

函數getpass現在已過時 使用termios

#include <termios.h>
#include <stdio.h>

void get_password(char *password)
{
    static struct termios old_terminal;
    static struct termios new_terminal;

    //get settings of the actual terminal
    tcgetattr(STDIN_FILENO, &old_terminal);

    // do not echo the characters
    new_terminal = old_terminal;
    new_terminal.c_lflag &= ~(ECHO);

    // set this as the new terminal options
    tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal);

    // get the password
    // the user can add chars and delete if he puts it wrong
    // the input process is done when he hits the enter
    // the \n is stored, we replace it with \0
    if (fgets(password, BUFSIZ, stdin) == NULL)
        password[0] = '\0';
    else
        password[strlen(password)-1] = '\0';

    // go back to the old settings
    tcsetattr(STDIN_FILENO, TCSANOW, &old_terminal);
}

int main(void)
{
    char password[BUFSIZ];

    puts("Insert password:");
    get_password(password);
    puts(password);
}

對於C / commandline / linux,請參閱:

man getch
man noecho

getch看到關於noecho 我自己從來沒有嘗試過。

在bash中,如果您使用read -s它不會在屏幕上回顯:

> read -s x
<type something><enter>
> echo $x
<whatever you typed>

為此,您將需要使用標准化或實際標准庫。

參見man 3 termiosman 3 ncurses

這是一個可以在Linux和其他Unix系統上運行的程序...

#include <stdio.h>

int main(void) {
  int f = open("/dev/tty", 0);
  char s[100];

  system("stty -echo > /dev/tty");
  f >= 0 && read(f, s, sizeof s) > 0 &&  printf("password was %s", s);
  system("stty echo > /dev/tty");
  return 0;
}

許多改進是可能的。 使用termios可能會更好,並且可以避免分叉和system()可能出現的安全問題。 使用標准I / O讀取密碼可能會更好。 (按照書面要求,鍵入的換行符必須刪除。)Linux和其他一些函數中有一個getpass()函數,但是將其標記為“過時。請勿使用它”。 處理SIGTSTP可能是一個好主意。

總的來說,我可能會尋找一個可以解決所有這些小問題的現有解決方案...

如果您有權訪問curses庫,則可以使用noecho 如果您使用的是Microsoft的C編譯器,則可以使用_getch 但是afaik,這兩者都將您與控制台綁定在一起。 如果您需要讀取stdin而不管它是來自控制台還是來自文件或管道命令,則需要告訴操作系統應如何處理控制台

     #include<conio.h>
     #include<iostream>
     using namespace std;
     int main(){
     char *pass = new char[20];
     cout<<"Password :";
     int i=0;   
     while( ( pass[i]=getch() ) != '\n' && pass[i] != '\r' && i<19 )
     {putchar('*'); i++;}
     pass[i]='\0';
     cout<<endl;
     if(strcmp("123456789",pass)==0 ) // do stuff
     return 0;}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM