2009-09-11 3 views
42

ho bisogno di leggere una password dallo standard input e voleva std::cin non eco i caratteri digitati dall'utente ...La lettura di una password da std :: cin

Come posso disattivare l'eco da std :: cin ?

Ecco il codice che sto attualmente in uso:

string passwd; 
cout << "Enter the password: "; 
getline(cin, passwd); 

Sto cercando un sistema operativo modo agnostica per fare questo. Here ci sono modi per farlo sia in Windows che in * nix.

+0

http://stackoverflow.com/questions/13687769/how-to-get-a-password-input-in-c-console-application/13687770#13687770 –

risposta

50

@ risposta wrang-wrang era davvero buono, ma non ha soddisfatto le mie esigenze, questo è ciò che il mio codice finale (che si basava su this) assomigliare: utilizzo

#ifdef WIN32 
#include <windows.h> 
#else 
#include <termios.h> 
#include <unistd.h> 
#endif 

void SetStdinEcho(bool enable = true) 
{ 
#ifdef WIN32 
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 
    DWORD mode; 
    GetConsoleMode(hStdin, &mode); 

    if(!enable) 
     mode &= ~ENABLE_ECHO_INPUT; 
    else 
     mode |= ENABLE_ECHO_INPUT; 

    SetConsoleMode(hStdin, mode); 

#else 
    struct termios tty; 
    tcgetattr(STDIN_FILENO, &tty); 
    if(!enable) 
     tty.c_lflag &= ~ECHO; 
    else 
     tty.c_lflag |= ECHO; 

    (void) tcsetattr(STDIN_FILENO, TCSANOW, &tty); 
#endif 
} 

Esempio:

#include <iostream> 
#include <string> 

int main() 
{ 
    SetStdinEcho(false); 

    std::string password; 
    std::cin >> password; 

    SetStdinEcho(true); 

    std::cout << password << std::endl; 

    return 0; 
} 
10

Non c'è niente nello standard per questo.

In unix, è possibile scrivere alcuni byte magici a seconda del tipo di terminale.

Utilizzare getpasswd se disponibile.

È possibile sistema() /usr/bin/stty -echo per disabilitare eco, e /usr/bin/stty echo Per attivarlo (di nuovo, in UNIX).

This guy explains come fare senza usare "stty"; Non l'ho provato da solo.

+0

Immagino che 'getpasswd' sarebbe di grande aiuto. Ma sto cercando un modo per farlo senza ricorrere alla magia nera del sistema operativo – Vargas

+2

@ Jonathan Il secondo link che hai menzionato è morto .. – cbinder

2

Solo un'idea di ciò che ho, si può leggere la password char per carattere, e dopo basta stampare backspace ("\ b") e forse "*".

+4

Se qualcuno sta registrando l'output del terminale su un file allora l'intera password sarà lì. Probabilmente non è una buona idea, quindi. – Artelius

+4

Lo stesso caso di qualcuno che registra tutti i tasti premendo :) – IProblemFactory

+1

Questo è insicuro, e una cattiva idea. È inaccettabile affidarsi all'altro lato del tubo per la propria sicurezza. E fai attenzione a non tubare sulla rete. E l'output di registrazione! = Keypress di registrazione: in genere si legge che il file di log viene letto per più persone rispetto a quelli con i diritti di scrittura sul programma di emulazione di terminale o per collegarsi a eventi di terminale o di sistema o driver di tastiera. – ignis

6

Se non si cura della portabilità, è possibile utilizzare _getch() in VC.

#include <iostream> 
#include <string> 
#include <conio.h> 

int main() 
{ 
    std::string password; 
    char ch; 
    const char ENTER = 13; 

    std::cout << "enter the password: "; 

    while((ch = _getch()) != ENTER) 
    { 
     password += ch; 
     std::cout << '*'; 
    } 
} 

C'è anche getwch() per wide characters. Il mio consiglio è di usare NCurse che è disponibile anche nei sistemi *nix.