【问题标题】:Storing passwords while keeping the integrity of getch()在保持 getch() 完整性的同时存储密码
【发布时间】:2010-12-21 06:41:16
【问题描述】:

有什么简单的方法可以存储用户输入的密码同时仍然隐藏密码?

  char password[9];
   int i;
   printf("Enter your password: ");
   for (i=0;i<9;i++)
   {
   password[i] = getch();
   printf("*");
   }
   for (i=0;i<9;i++)
   printf("%c",password[i]);
   getch();
   }

我想存储密码,这样我就可以做一个简单的if (password[i] == root_password),这样正确的密码就会继续。

【问题讨论】:

  • 您在 C++ 中使用 getch 而不是 cin.get 的任何特殊原因?
  • 没有理由。找不到其他合适的方式。
  • @Cody: getch 不回显输入,不像典型的 cin.get()

标签: c++ windows console


【解决方案1】:

您的问题似乎是您没有检查换行符 '\n' 或文件结尾。

printf("Enter your password: ");
char password[9];
int i;
for (i = 0; i < sizeof password - 1; i++)
{
    int c = getch();
    if (c == '\n' || c == EOF)
        break;
    }
    password[i] = c;
    printf("*");
}
password[i] = '\0';

这样,密码最终将成为一个 ASCIIZ 字符串,适合使用 putsprintf("%s", password) 或 - 最重要的是...

if (strcmp(password, root_password)) == 0)
    your_wish_is_my_command();

请注意,我们在密码中最多读取 8 个字符,因为我们需要一个额外的字符作为 NUL 终止符。如果你愿意,你可以增加它。

【讨论】:

  • 为什么它说我本节的所有变量都未声明?
  • Josh:如果你也在使用它,你是否包括了 printf() 和 getch()、strcmp() 的必要头文件?否则,我不能说没有看到您的确切代码 - 为什么不将其粘贴到上面的问题中,并列出确切的编译器错误和行号...?
  • 您在那里没有正确使用 sizeof。首先,您缺少 ( ),它返回以字节为单位的大小。用 sizeof 代替整个 hoopla,你可以只放 10。-1 会阻碍你,因为
  • 我正在使用 cstring、stdio、cmath 和 iostream 库。
  • @Josh:sizeof 不需要(),除非参数是一个类型(尽管我曾经被告知旧的MS C++ 编译器在这方面被破坏了)。根据return,它是一个关键字而不是函数调用,我不想鼓励读者通过像函数一样不必要地调用任何一个来混淆这两件事。我本可以将;i &lt; 8;(不是10)放在for-loop 条件中,但是如果您更改password 中的元素数量,这就会中断——这不是一个好习惯。如果您需要更多帮助,请发布您的确切代码。
【解决方案2】:

您需要在 Windows 中使用控制台 API。下面是一个在控制台窗口中禁用回显的 sn-p。函数SetConsoleMode() 用于控制回显(除其他外)。我保存旧模式,以便在找回密码后恢复控制台。

另外,*ConsoleMode() 函数需要控制台输入缓冲区的句柄。 CreateFile() 的 MSDN 文档中描述了如何获取这些缓冲区的句柄。

int main(int argc, char* argv[])
{
    char password[100] = { 0 };
    printf("Enter your password: ");

    HANDLE hConsole = ::CreateFile("CONIN$", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

    DWORD dwOldMode;
    ::GetConsoleMode(hConsole, &dwOldMode);
    ::SetConsoleMode(hConsole, dwOldMode & ~ENABLE_ECHO_INPUT);

    bool bFinished = false;
    while(!bFinished) {
        if(!fgets(password, sizeof(password) / sizeof(password[0]) - 1, stdin)) {
            printf("\nEOF - exiting\n");
        } else
            bFinished = true;
    }

    ::SetConsoleMode(hConsole, dwOldMode | ENABLE_ECHO_INPUT);
    printf("\nPassword is: %s\n", password);

    return 0;
}

【讨论】:

    【解决方案3】:

    因为我们在 C++ 和 Windows 中这样做:

    #include <iostream>
    #include <string>
    #include <conio.h> //_getch
    #include <Windows.h> //VK_RETURN = 0x0D
    
    using namespace std;
    
    string read_password()
    {
        string pass;
        cout << "Enter your password: ";
    
        int character = 0;
        while(VK_RETURN != (character = _getch()) )
        {
            cout << '*';
            pass += static_cast<char>(character);
        }
    
        cout << std::endl;
        return pass;
    }
    
    int main ()
    {
        string root_password = "anypass123";
        string pass = read_password();
    
        if (pass == root_password)
        {
            cout << "password accepted" << endl;
        }
    
        return 0;
    }
    

    编译和测试

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 1970-01-01
      • 2016-05-09
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多