2009-09-11 30 views
42

tôi cần phải đọc mật khẩu từ đầu vào tiêu chuẩn và muốn std::cin không để echo các ký tự gõ bởi người sử dụng ...Đọc một mật khẩu từ std :: cin

Làm thế nào tôi có thể vô hiệu hóa các âm vang từ std :: cin ?

đây là mã mà tôi hiện đang sử dụng:

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

Tôi đang tìm kiếm một cách OS thuyết bất khả tri để làm điều này. Here có nhiều cách để thực hiện việc này trong cả Windows và * nix.

+0

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

Trả lời

50

@ wrang-wrang câu trả lời là thực sự tốt, nhưng không đáp ứng nhu cầu của tôi, đây là những gì mã cuối cùng của tôi (được dựa trên this) trông giống như: sử dụng

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

mẫu:

#include <iostream> 
#include <string> 

int main() 
{ 
    SetStdinEcho(false); 

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

    SetStdinEcho(true); 

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

    return 0; 
} 
10

Không có gì trong tiêu chuẩn cho việc này.

Trong unix, bạn có thể viết một số byte ma thuật tùy thuộc vào loại thiết bị đầu cuối.

Sử dụng getpasswd nếu có.

Bạn có thể hệ thống() /usr/bin/stty -echo để tắt tiếng vọng và /usr/bin/stty echo để bật lại (một lần nữa, trên unix).

This guy explains cách thực hiện mà không sử dụng "stty"; Tôi không thử nó.

+0

tôi đoán 'getpasswd' sẽ thực sự giúp đỡ. Nhưng tôi đang tìm một cách để thực hiện điều này mà không phải định kỳ lại với ma thuật hệ điều hành màu đen – Vargas

+2

@Jonathan Liên kết thứ hai mà bạn đã đề cập là đã chết .. – cbinder

2

Chỉ ý tưởng những gì tôi có, bạn có thể đọc được mật khẩu char bởi char, và sau đó chỉ cần in xóa lùi ("\ b") và có thể '*'.

+4

Nếu ai đó đang ghi đầu ra của thiết bị đầu cuối vào một tệp thì toàn bộ mật khẩu sẽ ở đó. Có lẽ không phải là một ý tưởng tốt, sau đó. – Artelius

+4

Trường hợp tương tự khi ai đó đăng nhập tất cả phím bấm :) – IProblemFactory

+1

Điều này là không an toàn và là một ý tưởng tồi. Nó không thể chấp nhận để dựa vào phía bên kia của đường ống cho an ninh của riêng bạn. Và hãy cẩn thận không để ống trên mạng. Ghi nhật ký: bạn thường sẽ cho phép người dùng đọc tệp nhật ký của mình với nhiều người hơn những người có quyền ghi đè lên chương trình giả lập thiết bị đầu cuối hoặc móc nối vào thiết bị đầu cuối hoặc sự kiện hệ thống hoặc trình điều khiển bàn phím. – ignis

6

Nếu bạn không quan tâm đến tính di động, bạn có thể sử dụng _getch() trong 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 << '*'; 
    } 
} 

Ngoài ra còn có getwch() cho wide characters. Lời khuyên của tôi là bạn sử dụng NCurse có sẵn trong các hệ thống *nix.