Linux下用C语言实现简单的密码登录

通常,我们在切换计算机用户时,会需要输入密码。在Linux命令行下,密码不可见;在Windows下,密码显示的则是··········的一串小黑点,或者登陆某一网站账号时密码为********的一串星号,其目的都是来隐藏密码。而这种密码的显示方式怎样是怎样实现的呢,今天,我就用C语言在Linux下简单实现一下。

一、输入密码不回显:

1、首先,我们需要了解几个函数以及结构体:

(1)、结构体struct termios:

struct termios{
           tcflag_t c_iflag;/*input modes输入模式标志*/
           tcflag_t c_oflag;/*output modes输出模式标志*/
           tcflag_t c_cflag;/*contol modes控制模式标志*/
           tcflag_t c_lflag;/*local modes本地模式标志*/
           cc_t c_cc[NCCS];/*contol chars控制字符*/

};
/*这是一个标准终端接口的结构体,其中5个成员中我们会用到c_lflag这个本地模式*/
/*
    c_lflag会用到的几个参数:
    ECHO//显示输入字符
    ICANON//使用标准输入输出
*/

(2)tcsetattr()与tcgetattr()函数:
函数原型:

#include<termios.h>
int tcgetattr(int fd,struct termios * termios_p);//获取终端参数
int tcsetattr(int fd,int optional_actions,const struct termios *termios_p);//设置终端参数

tcgetattr()函数:
返回值:成功返回0,失败返回-1,失败时接口设置errno标识
参数:

/*
fd为终端文件描述符:
0表示stdin
1表示stdout
2表示stderr

termios_p为结构体struct termios*类型指针,其指向的空间用来存储tcgetatrr()函数获取到的fd的的参数。
*/

tcsetattr()函数:
返回值:成功返回0,失败返回-1并设置errno
参数:

fd与tcgetattr()函数一样,为终端文件描述符

optional_actions则是用来控制修改后设置的参数起作用的时间(有3个):
TCSANOW     //立即生效
TCSADRAIN   //等待所有数据传输完毕后生效
TCSAFLUSH   //等待所有数据传输完毕并且清空输入输出缓存区后生效

termios_p存放新的重新设置的参数的结构体变量

2、代码实现:

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

int main()
{
    struct termios old, new;//old保存当前的终端参数,new用来保存修改后的终端参数

    tcgetattr(0, &old);//将tcgetattr()获取到的stdin(标准输入流)的参数存到old中
    new = old;//将该参数复制一份到new中

    new.c_lflag &= ~( ECHO | ICANON);//修改new中的ECHO和ICANON参数,使得new为不回显输入内容

    tcsetattr(0,  TCSANOW ,&new);//将修改后的new设置为stdin的新的参数,并立即生效

    char buf[20] = {0};
    int i = 0;

    while( (strncmp("redhat", buf, 6)) && i<5){
        memset(buf, 0, 20);//每次重新输入以前都要清空一次buf
        fgets(buf, 20, stdin);  
        i++;
    }
    if(i>=5){
        printf("密码输入错误超过5次,登录失败!\n");
        printf("buf: %s\n", buf);
    }
    else{
        printf("登陆成功!\n");
    }
    tcsetattr(0, TCSANOW, &old);//登陆成功后恢复原有终端参数,正常回显

    return 0;
}

二、输入密码时显示**********

1、实现:

只要搞清了不回显的实现方式,相较于不回显,显示**** 就比较简单了,代码如下:

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

int main(void)
{
    struct termios old,new;
    tcgetattr(0,&old);
    new = old;
    new.c_lflag &= ~(ECHO|ICANON);

    char passwd_stdin[20]={0};
    char passwd_true[]="hello";
    char ch;
    int i=0;

    while(1)
    {
        tcsetattr(0, TCSANOW, &new);//进入循环将stdin设置为不回显状态
        scanf("%c",&ch);//在不回显状态下输入密码
        tcsetattr(0, TCSANOW, &old);//每次输入一个密码的字符就恢复正常回显状态
        if(i==20 || ch == '\n')//输入回车符表示密码输入完毕,退出循环;或者超出密码长度退出循环
            break;
        passwd_stdin[i] = ch;//将输入的单个字符依次存入数组中

        printf("*");//在回显状态下输出*
        i++;
    }
    /*比较从终端输入的密码与设定好的密码是否相同,相同打印一些信息,表示登陆成功;不同做出一些操作,对非正常登陆作出保护性措施*/
    if(!strcmp(passwd_stdin,passwd_true)){
        printf("登陆成功!\n");
        system("cat passwd.c");
    }
    else{
        printf("登录失败!\n");
        //system("shutdown -h now");
    }
    return 0;
}

2、运行结果:

成功:
这里写图片描述
失败:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值