使用C++模拟动态密码验证

来源:互联网 发布:c语言中 ||是什么意思 编辑:程序博客网 时间:2024/06/08 15:22

  • 前言
  • 实现原理
  • 编程实现
    • 核心函数
    • 每隔一段时间修改一次
    • 主程序
      • 安全验证
      • 生成器
      • 主循环
  • 完整源代码

前言

主要是最近特别想写一个保密的网站系统。然后自己大概考虑了一个实现方法,然后经过测试发现有效。后来在网上找有没有更好的解决方案,然后惊奇地发现这方面居然没有人来提供教程。

然后本菜鸡就把自己的方法放送出来,方便大家在进行各种开发的时候使用动态密码算法。

实现原理

其实整个原理是比较简单的。

比如说现在有两个设备,服务端和客户端。

两部设备同时拥有时钟和一套相同的算法。当用户需要一个新的动态密码时,两个设备会通过各自的时钟,使用相同的算法来计算出两个密码。此时,用户手中的密码应该是客户端的密码。在两个设备的时钟相同时,对应生成的密码也相同。用户输入客户端提供的密码到服务器进行验证,若密码相同,则验证通过。

所以现在需要模拟生成密码的算法。我在这里提供了一个很菜的算法,大家可以拿来参考一下。

编程实现

核心函数

这里面最核心的函数是ctime库中的两个函数:

time_t tt=time(NULL);tm *t=localtime(&tt);

time函数用于获取系统时间,而localtime函数则将time_t数据转换成可读的数据。

读取时间的方法如下:

t->tm_year+1900 //年t->tm_mon+1     //月t->tm_mday      //日t->tm_hour      //小时t->tm_min       //分钟t->tm_sec       //秒

使用这些数据来计算一个密码出来。

每隔一段时间修改一次

这个可以通过对秒整除和取余来实现。

比如说,我想让这个代码20秒换一次,那么我就可以:

sec=sec/code_time+1;

这样一来,sec变量中存储的值只有20秒才会变化一次。

主程序

安全验证

这个并不是必要的,只是为了防止任何人都能轻易使用这套程序。

//以下为全局内容string password="123456";string input(){    char geted=getch();    string outed;    while(geted!=13)    {        cout<<"*";        outed+=geted;        geted=getch();    }    cout<<endl;    return outed;}//以下为主程序中的内容    cout<<"Current security code : UNKNOWN"<<endl;    cout<<"Code change : UNKNOWN"<<endl;    string check;    int timesss=1;    for(timesss=1;timesss<=3;timesss++)    {        cout<<"Security pass required : ";        check=input();        if(check==password) break;        else cout<<"[ERROR]Invalid pass! Chances remained : "<<3-timesss<<endl;    }    if(timesss>3)    {        cout<<"[DENIED]SECURITY PASS FAILED!"<<endl;        getch();        return 0;    }

这个小型密码安全验证提供三次输入密码机会,并且自动将输入的密码变成“*”,以增加安全性。

生成器

使用这个函数来根据当前时间计算一个新的动态密码。

int code_time=20;   //安全代码刷新时间 int code_len=6;     //安全代码长度 string trim(string a,int len){    string b;    len=min(len,(int)a.length());    for(int i=0;i<len;i++)    {        b+=a[i];    }    return b;}string generate(tm *t,int len){    int year=t->tm_year+1900;    int mon=t->tm_mon+1;    int day=t->tm_mday;    int hour=t->tm_hour;    int min=t->tm_min;    int sec=t->tm_sec;    unsigned int result=(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*min*min*min*year*year*mon*mon*day*day+day*day*(sec/code_time+1)*(sec/code_time+1)*(hour+1)*(hour+1)*(min+1)-min;    int a=result%2147480000+100000;    char str[55];    itoa(a,str,10);//将数字转换成字符数组存储到str中    return trim(str,len);}

trim(string)函数用于剪切字符串,提取字符串的前6位。

generate(tm,int)函数提供了一个非常暴力的算法,当然你也可以更换其中的算法,使得它随机性更高。

主循环

如果你想在程序启动的时候一直动态获取密码,并且显示还剩多长时间改变,那么你可以参照以下的代码:

    while(true)    {        tt=time(NULL);        t=localtime(&tt);        int time_remain=code_time-(t->tm_sec)%code_time-1;        if(time_remain==code_time-1||!out)        {            out=true;            system("cls");            cout<<"Current security code : "<<generate(t,6)<<endl;            cout<<"Code change : "<<time_remain;            Sleep(100);        }        else        {            cout<<"                                \rCode change : "<<time_remain;        }        Sleep(100);    }

像这样。每隔100毫秒读取一次系统时间,如果系统察觉到了密码应该变化,那么就重新计算一组密码。

完整源代码

在这里放出程序的完整源代码,方便进行学习、交流。

如果有更好的建议或者我讲的东西有任何问题,欢迎私信我,谢谢!

#include<iostream>#include<ctime>#include<string>#include<stdlib.h>#include<stdio.h>#include<windows.h>#include<conio.h>using namespace std;int code_time=20;   //安全代码刷新时间 int code_len=6;     //安全代码长度 string password="123456";//保护密码 string input(){    char geted=getch();    string outed;    while(geted!=13)    {        cout<<"*";        outed+=geted;        geted=getch();    }    cout<<endl;    return outed;}string trim(string a,int len){    string b;    len=min(len,(int)a.length());    for(int i=0;i<len;i++)    {        b+=a[i];    }    return b;}string generate(tm *t,int len){    int year=t->tm_year+1900;    int mon=t->tm_mon+1;    int day=t->tm_mday;    int hour=t->tm_hour;    int min=t->tm_min;    int sec=t->tm_sec;    unsigned int result=(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*(sec/code_time+1)*min*min*min*year*year*mon*mon*day*day+day*day*(sec/code_time+1)*(sec/code_time+1)*(hour+1)*(hour+1)*(min+1)-min;    int a=result%2147480000+100000;    char str[55];    itoa(a,str,10);    return trim(str,len);}int main(){    time_t tt=time(NULL);    tm *t=localtime(&tt);    bool out=false;    cout<<"Current security code : UNKNOWN"<<endl;    cout<<"Code change : UNKNOWN"<<endl;    string check;    int timesss=1;    for(timesss=1;timesss<=3;timesss++)    {        cout<<"Security pass required : ";        check=input();        if(check==password) break;        else cout<<"[ERROR]Invalid pass! Chances remained : "<<3-timesss<<endl;    }    if(timesss>3)    {        cout<<"[DENIED]SECURITY PASS FAILED!"<<endl;        getch();        return 0;    }    while(true)    {        tt=time(NULL);        t=localtime(&tt);        int time_remain=code_time-(t->tm_sec)%code_time-1;        if(time_remain==code_time-1||!out)        {            out=true;            system("cls");            cout<<"Current security code : "<<generate(t,6)<<endl;            cout<<"Code change : "<<time_remain;            Sleep(100);        }        else        {            cout<<"                                \rCode change : "<<time_remain;        }        Sleep(100);    }    return 0;}
原创粉丝点击