虚位密码 是一个很有意思的功能,不知道什么时候开始变成了智能锁的标配功能之一。
虚位密码的意思是你输入的密码位数不固定,但是只要你输入的密码有你当初设定的密码,那么就认为是正确的;反之就是错误的。
虚位密码功能在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上验证是因为他足够代表嵌入式设备的实力。(单片机实力很差是公认的事实)
运行结果:
与上面类似于,由于嵌入式代码是一种没有终止的,只要给电就一直跑的代码,所以可以看简单这些代码一直在循环(现在的计算机也是这样)。
输入给定的元素都很快。而且速度均在一秒内给出。所以证明虚位密码功能在上面还是很简单就能实现的。