至诚计科刘欣

博客园 首页 新随笔 联系 订阅 管理

虚位密码 是一个很有意思的功能,不知道什么时候开始变成了智能锁的标配功能之一。

虚位密码的意思是你输入的密码位数不固定,但是只要你输入的密码有你当初设定的密码,那么就认为是正确的;反之就是错误的。

虚位密码功能在C++ 或者 Java中最类似的应该是String类里面查找+比较功能。

这里仅仅用最简单的算法来进行实现,不求特别复杂的实现。

很多的时候工程里面要取舍 实现的质量(从效率和占用来衡量) 和 实现的速度(编码的时间。Java之所以流行就是因为他的编码速度比较快【一次编译,处处运行】,虽然Java面向对象实现的不是那么完美)。

这里扯远了。本次只实现两个版本的代码:标准C++(运行平台:PC) 和 嵌入式C++(Arduino用的C++)


 思路

对于给定的字符串 s,我们首先获取其的首字符 c,之后再用户输入的字符串 p中,去寻找 c所在的位置,再从c所在的位置切取长度与 给定的字符串s 一样的字符串,进行比较(C语言里面加起来减的比较),若比较结果为0,则认为找到该串,返回成功的结果;反之,如果为能在给定的区域找到给定的字符串,即搜索的位置已达末尾,以及分割出来的子串长度已经小于给定的字符串长度,则认为失败,返回失败的结果。

结果

成功:true,找到相似的字符串

失败:false,未找到相似的字符串


 下面是一个标准C++的实现,C++版本为11

 1 #include<string>
 2 #include <iostream>
 3 
 4 int main()
 5 {
 6     int findlength = 0; //寻找的长度
 7     bool isOK = false; //找到了就是true
 8     std::string passwd = "218519"; //原始密码
 9     std::string userinputpasswd;
10     std::cout << "请输入密码:";
11     std::cin >> userinputpasswd;
12     while (findlength < userinputpasswd.size())
13     {
14         if (findlength != 0)//非首次搜索跳过已搜索的位置,否则会陷入死循环。
15         {
16             findlength++;
17         }
18         findlength = userinputpasswd.find(passwd.front(), findlength);//从头开始找到第一个元素和密码匹配的位置
19         if (findlength != std::string::npos)//找不到就要break了。
20         {
21             std::string substr = userinputpasswd.substr(findlength, passwd.size());
22             if (substr.size() < passwd.size())
23             {
24                 break;
25             }
26             int comp =substr.compare(passwd);
27             if (comp == 0)
28             {
29                 isOK = true;
30                 break;
31             }
32         }
33         else {
34             break;
35         }
36     }
37     std::cout << (isOK ? "密码正确" : "密码错误")<<std::endl;
38     return 0;
39 }

运行结果:

给定的字符串:218519

测试字符串:218519

结果正确。

输入字符串:6262626564542621851965656

输入的字符串含有字串:”218519“,结果应为正确。

输出结果:密码正确

结果正确

输入的字符串:123456

输出结果:密码错误。

结果正确

输入密码:5161816+1856165185615316

输出结果:密码错误。

结果正确。

这就是一个简单的实现,在我的Workstation(工作站)上面好像不需要一秒就能完成。但是我们知道虚位密码功能是用于嵌入式设备上面的,嵌入式设备通常是非常的week。所以还要在Arduino Uno上验证。(ATMEGA328P 已经很week了);


Arduino uno是一块基于Atemel 爱特梅尔(现已被Microchip 微芯 收购)Atmega 328p的8位嵌入式开发板,由于其支持C++的特性已经简单易用受到全世界范围内嵌入式爱好者(包括艺术家)的喜爱。

atmega328p在Arduino Uno上运行于16MHz的主频状态,正常应该运行在20Mhz的状态。这是为了兼容前代设备。

Arduino代码:

 1 int findlength = 0;//寻找的位置
 2 String passwd = "218519";
 3 bool isOK = false;
 4 // The setup() function runs once each time the micro-controller starts
 5 void setup()
 6 {
 7     Serial.begin(9600);
 8     Serial.println("Please enter you passwd:");
 9 }
10 
11 // Add the main program code into the continuous loop() function
12 void loop()
13 {
14     findlength = 0;
15     isOK = false;
16     if (Serial.available())
17     {
18         String pass = Serial.readString();
19         Serial.println(pass);
20         Serial.flush();
21         while (findlength < pass.length())
22         {
23             if (findlength != 0)
24             {
25                 findlength++;
26             }
27             findlength = pass.indexOf(passwd.charAt(0), findlength);
28             if (findlength == -1)
29             {
30                 break;
31             }
32             else {
33                 String substr = pass.substring(findlength, findlength + passwd.length());
34                 int comp = passwd.compareTo(substr);
35                 if (comp == 0)
36                 {
37                     isOK = true;
38                     break;
39                 }
40             }
41         }
42         Serial.println(isOK ? "OK" : "NO");
43         Serial.println("Please enter you passwd:");
44     }
45     
46     delay(500);
47 }

这是标准的Arduino代码可以适用于任何兼容Arduino的设备(比如ESP8266),这里在Arduino Uno上验证是因为他足够代表嵌入式设备的实力。(单片机实力很差是公认的事实)

运行结果:

与上面类似于,由于嵌入式代码是一种没有终止的,只要给电就一直跑的代码,所以可以看简单这些代码一直在循环(现在的计算机也是这样)。

输入给定的元素都很快。而且速度均在一秒内给出。所以证明虚位密码功能在上面还是很简单就能实现的。

 

posted on 2019-02-15 15:45  至诚计科刘欣  阅读(1311)  评论(0编辑  收藏  举报