-
- import redis.clients.jedis.Jedis;
-
- import java.util.Scanner;
- import java.util.regex.Pattern;
-
- /**
- * @author:tengsen
- * @create: 2022-10-03 06:21
- * @Description: 模拟手机验证码
- * 手机验证码功能
- * 要求:
- * 1、输入手机号,点击发送后随机生成6位数字码,2分钟内有效
- * 2、输入验证码:点击验证,返回成功或者失败
- * 3、每个手机号每天只能获取3次验证码
- *
- * 数据结构设计:
- * (1)普通键值对set: key:"phone"+具体电话号码+"p", value: 当天该号码已经发送的次数, 过期时间为1天(24*60*60)
- * (2)普通键值对set: key:"code"+具体电话号码+"c", value: 具体验证码, 过期时间为2min(2*60)
- * (3) hash: key "hash"+具体电话号码+"h", field: 具体验证码, value:已经请求验证的次数(最多尝试验证3次)
- * (4) 注意: 验证成功、发送新的验证码或验码已经过期时,都要时要根据key来删除(2)和(3)
- *
- **/
- public class verifyCode {
-
- public static void main(String[] args) {
- //连接redis
- Jedis jedis = new Jedis("127.0.0.1",6380);
-
- // 注意!注意!注意!
- // 此处为密码登录,若无密码可注释掉
- // 注释还是不注释或者具体密码是多少可根据实际情况调整
- // 我这里使用的密码是123
- jedis.auth("123");
-
- //测试redis是否连接成功
- String ping = jedis.ping();
- System.out.println(ping);
-
- //输入手机号
- Scanner scanner = new Scanner(System.in);
- System.out.print("请输入手机号:");
- String phone;
- while (true){
- phone = scanner.nextLine();
- if(isValidPhone(phone)){
- break;
- }
- System.out.println("手机号格式输入错误,正确的格式要求为:");
- System.out.println("第一位数字是1,第二位数字只能是3或4或5或6或7或8或9,剩下的九位数字可以是0-9之间任意一位数字,共11位");
- System.out.print("请重新输入手机号:");
- }
-
- boolean login = false;
- boolean exit = false;
- //token作为用户想不想获取验证码的一个标志符
- String token = "";
- System.out.print("是否获取验证码:(y/n):");
- while (true){
- token = scanner.nextLine();
- if (isValidToken(token)){
- break;
- }
- System.out.print("输入非法,请重新输入是否获取验证码(y/n):");
- }
-
- if(token.equals("y")){
-
- //发送验证码
- boolean flag = sendVerifyCode(phone,jedis);
- if(flag){
- String codeKey = "code"+phone+"c";
- String realCode = jedis.get(codeKey);
- System.out.println("!提示:收到的验证码为:"+realCode);
- }
- System.out.print("登录校验请输入(v),重新发送验证码请输入(r),退出登录请输入(e):");
- while (true){
- String select = scanner.nextLine();
- System.out.println();
- if(select.equals("v")){
- //校验验证码
- System.out.print("请输入验证码:");
- while (true){
- String code = scanner.nextLine();
- Integer i = verifyCode(phone,code,jedis);
- if(i.equals(1)){
- login = true;
- break;
- }else if(i.equals(0)){
- //验证失败已达3次或者验证码过期
- break;
- }
- System.out.print("重新输入验证码请输入(continue),任意输入终止本轮验证:");
- String select2 = scanner.nextLine();
- if(!select2.equals("continue")){
- System.out.println("本轮验证终止");
- break;
- }
- System.out.print("请重新输入验证码:");
- }
- }else if(select.equals("r")){
- //重新发送验证码
- boolean flag2 = sendVerifyCode(phone,jedis);
- String codeKey = "code"+phone+"c";
- String realCode = jedis.get(codeKey);
- if (flag2){
- System.out.println("!提示:收到的验证码为:"+realCode);
- }else{
- System.out.println("!提示:已存在的验证码为:"+realCode);
- }
-
- }else if(select.equals("e")){
- //退出登录
- exit = true;
- }else {
- System.out.println("输入非法,只能输入v或r或e,请重新输入您的选择");
- }
- if (exit){
- System.out.println("成功退出");
- break;
- }
- if (login){
- break;
- }
- System.out.println();
- System.out.print("登录校验请输入(v),重新发送验证码请输入(r),退出请输入(e):");
- }
- if (login){
- System.out.println("登录成功");
- }else {
- System.out.println("登录失败");
- }
- }else {
- System.out.println("您选择了n,已经退出程序,如需再次使用手机验证码功能,请重新启动程序");
- }
- }
-
- //校验手机号格式的函数
- public static boolean isValidPhone(String phone){
- if((phone!=null)&&(!phone.isEmpty())){
- return Pattern.matches("^1[3-9]\\d{9}$",phone);
- }
- return false;
- }
-
- //校验token(y/n)输入是否合法的函数
- public static boolean isValidToken(String token){
- if((token!=null)&&(!token.isEmpty())){
- return token.equals("y")||token.equals("n");
- }
- return false;
- }
-
- //发送验证码
- public static boolean sendVerifyCode(String phone,Jedis jedis){
- String phoneKey = "phone"+phone+"p";
- String codeKey = "code"+phone+"c";
- String hashKey = "hash"+phone+"h";
-
- String phoneValue = jedis.get(phoneKey);
- if(phoneValue == null){
- jedis.setex(phoneKey,24*60*60,"1");
- }else {
- //规定发出一个验证码60秒后,才能发送新的验证码,原定一个一个验证码存活120秒,所以ttl要减60
- Long ttl = jedis.ttl(codeKey);
- ttl-=60;
- if(ttl>=0){
- System.out.println("验证码已存在,"+(ttl)+"秒后可重新尝试");
- return false;
- }else{
- if(Integer.parseInt(phoneValue)<3){
- jedis.incr(phoneKey);
- }else {
- System.out.println("今天该手机号验证码发送次数已经超过3次,今天已经不能再发送验证码");
- return false;
- }
- }
- }
-
- //生成验证码
- String code = generateCode();
-
- jedis.setex(codeKey,2*60,code);
- jedis.hset(hashKey,code,"0");
- System.out.println("验证码发送成功");
- return true;
- }
-
- //校验验证码
- public static Integer verifyCode(String phone,String code,Jedis jedis){
- String codeKey = "code"+phone+"c";
- String hashKey = "hash"+phone+"h";
-
- //判断此时的验证码是否已经过期
- Integer ttl = Math.toIntExact(jedis.ttl(codeKey));
-
- if(ttl.equals(-2)){
- System.out.println("验证码已经过期,请重新发送新的验证码");
-
- //根据codeKey删除code,根据hashKey删除该code已经验证的次数
- deleteCode(codeKey,hashKey,jedis);
- return 0;
- }
-
- String codeValue = jedis.get(codeKey);
- String hashValue = jedis.hget(hashKey,codeValue);
- int times = Integer.parseInt(hashValue);
- if(times<3){
- if(code.equals(codeValue)){
- System.out.println("验证成功");
-
- //根据codeKey删除code,根据hashKey删除该code已经验证的次数
- deleteCode(codeKey,hashKey,jedis);
- return 1;
- }else{
- Long aLong = jedis.hincrBy(hashKey, codeValue, 1);
- System.out.println("验证码错误,请重新输入,你还可以尝试"+(3-aLong)+"次");
- return 2;
- }
- }else {
- System.out.println("你已经验证过三次,达到上限,请重新发送验证码");
-
- //根据codeKey删除code,根据hashKey删除该code已经验证的次数
- deleteCode(codeKey,hashKey,jedis);
- return 0;
- }
-
- }
-
- //生成6位随机验证码的函数
- public static String generateCode(){
- String code = "";
- for (int i = 0; i < 6; i++) {
- code += (int)(Math.random()*10);
- }
- return code;
- }
-
- //根据codeKey删除code,根据hashKey删除该code已经验证的次数
- public static void deleteCode(String codeKey,String hashCode,Jedis jedis){
- jedis.del(codeKey);
- jedis.del(hashCode);
- }
- }






(1) 编辑redis的配置文件,后缀为.conf:

(2)使用ctrl+F快捷键查找port,需要设置为自己想要redis占用的端口:

(3)查找requirepass,将登录该redis的密码设置好:

我这里使用的是下面的指令(redis服务端启动命令+要使用的配置文件):
redis-server.exe redis.windows-6380.conf

(1)相关工具百度网盘分享:
这个jar包相当于辅助组件,因为java本身是没有redis的,所以需要引入该工具。
链接:https://pan.baidu.com/s/1FBwvbRv3ickkrB58VNklWA?pwd=9999
提取码:9999
--来自百度网盘超级会员V5的分享

对于以上两个工具,也可以去redis官网下载其他版本。
(2)下载好jedis-2.9.0.jar后,需要将该jar包引入项目中,这里以idea为实操工具
1>在项目src目录下新建lib文件夹。
2>在文件(File)中找到项目结构(Project Structure...),点击打开:

3>在项目结构中找到库(Libraries),点击+号:

4>继续点击:

5>找到lib文件夹,选中后点击确定:

6>然后选中Jar Directory,点击确定:

7>继续选择确定:
8>继续选择确定:

9>将该jar包复制进lib文件夹中:

10>查看目录,效果如红圈内所示: