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

来源:互联网 发布:程序员为什么转行? 编辑:程序博客网 时间:2024/05/21 18:31

通常,我们在切换计算机用户时,会需要输入密码。在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表示stdin1表示stdout2表示stderrtermios_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、运行结果:

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

1 0
原创粉丝点击