当前位置: 首页 > news >正文

JAVA实战小项目——输入验证码

生活中有很多需要登陆账户的情况,在输入账号密码以后还需要输入验证码,本文将实现一个输入一个四位验证码的小项目。

验证码是仅由0-9数字和所有字母构成,并且生成的验证码完全是随机的。那么先拿一个字符串保存所有的数字和字母,然后由这个字符串随机生成。

那么就可以在这个字符串的长度范围内,随机生成一个下标,再根据这个下标取出字符串中的那个字符,如此再生成第二个数字或字母,直到第四个。这样就生成了随机的四位验证码。

import java.util.Random;
import java.util.Scanner;public class Test2 {public static void main(String[] args) {char[] VerCode=new char[4];Random rand=new Random();String RandomStr="0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";for(int i=0;i<VerCode.length;i++){int randIndex=rand.nextInt(RandomStr.length());VerCode[i]=RandomStr.charAt(randIndex);}}
}

我们都知道,验证码的验证是不区分大小写的,所以可以在用户输入前先转换成小写,然后用户输入后,也都转换成小写再进行比较是否相等。不过转换成小写先要将这个字符数组转为string类型,因为string类里面是封装了转小写的功能。

但是当tostring转为string类了以后,它确实可以转小写,可是打印出来看的时候又不对了

这时候它显示的不再是它的内容了,而是它的地址,那为什么会这样呢?

数组作为一种引用类型,自然也继承了object类,而在object中的tostring就是转为一串地址,数组类中也没有去重写这个方法,固然使用的还是object中的tostring方法。同样里面的equals也没有重写,所以在后续进行比较时也将会比较地址,这种比较方式肯定不是我们想要的,想要比较内容就必须重写方法。

既然tostring还要重写那干脆就不要tostring了,直接用这个字符数组来初始化一个新建string类型的code,然后再和输入进行比较

        String code=new String(VerCode);System.out.println(code);System.out.println("请输入验证码:");Scanner sc=new Scanner(System.in);String input=sc.nextLine();

在string类里面已经封装了一个忽略大小写的比较方法equalsIgnoreCase,直接用起来就很方便,不过有个细节需要注意,应该要让code去调用这个比较方法而不能用input,因为有的用户可能很坏,直接输入一个空的。

        if(code.equalsIgnoreCase(input))System.out.println("输入正确");elseSystem.out.println("验证码错误");

不管输入正确与否,程序都会结束,需要重新获取验证码,这也合乎常理,毕竟实际运用中只要输入错误,那么这个验证码就失效了,需要重新生成验证码。

最后代码和运行结果如下:

import java.util.Scanner;
import java.util.Random;
import java.util.Arrays;public class Test {public static void main(String[] args) {char[] VerCode=new char[4];Random rand=new Random();String RandomStr="0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";for(int i=0;i<VerCode.length;i++){int randIndex=rand.nextInt(RandomStr.length());VerCode[i]=RandomStr.charAt(randIndex);}String code=new String(VerCode);System.out.println(code);System.out.println("请输入验证码:");Scanner sc=new Scanner(System.in);String input=sc.nextLine();if(code.equalsIgnoreCase(input))System.out.println("输入正确");elseSystem.out.println("验证码错误");}
}

那如果非要去重写string类里面的方法呢,想按照那就要自己去造一个类,里面有一个字符型数组,然后在里面重写tostring方法,要进行比较还要重写equals和hashcode。equals和hashcode可以自动生成:右键点击生成,然后选择equals和hashcode,即可自动生成。

而tostring需要让它输出内容而非地址,在tostring中就应该自己用arr字符数组来给字符串s赋值。

    public String toString() {String s = new String(arr);return s;}

顺便这个类里面我们还可以做一件事,将所有的大写字母转小写,这样方便后续的比较。就可以提供一个LowerArr的方法:

    public LowerArr(char[] arr){this.arr=new char[arr.length];for(int i=0;i<arr.length;i++){if(arr[i]>='A'&&arr[i]<='Z'){this.arr[i]=(char)(arr[i]+32);}else{this.arr[i]=arr[i];}}}

那么整个类就实现或重写了如下功能:

import java.util.Arrays;
import java.util.Objects;public class LowerArr {private final char[] arr;public LowerArr(char[] arr){this.arr=new char[arr.length];for(int i=0;i<arr.length;i++){if(arr[i]>='A'&&arr[i]<='Z'){this.arr[i]=(char)(arr[i]+32);}else{this.arr[i]=arr[i];}}}@Overridepublic String toString() {String s = new String(arr);return s;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;LowerArr lowerArr = (LowerArr) o;return Objects.deepEquals(arr, lowerArr.arr);}@Overridepublic int hashCode() {return Arrays.hashCode(arr);}
}

在主函数中就可以创建这个类而不是string类,只有自己写的这个类里面的tostring和比较equals才能达到想要的功能

主函数代码如下:

import java.util.Random;
import java.util.Scanner;public class Test {public static void main(String[] args) {char[] VerCode=new char[4];Random rand=new Random();String RandomStr="0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";for(int i=0;i<VerCode.length;i++){int randIndex=rand.nextInt(RandomStr.length());VerCode[i]=RandomStr.charAt(randIndex);}LowerArr lowercode=new LowerArr(VerCode);System.out.println(lowercode);Scanner sc=new Scanner(System.in);String input=sc.nextLine();char[] inputChar=input.toCharArray();LowerArr inputLower=new LowerArr(inputChar);System.out.println(inputLower);if(lowercode.equals(inputLower))System.out.println("输入正确");elseSystem.out.println("验证码错误");}
}

如此一来,用自己类重写的tostring和equals的方式代码量比较大,而且我们仅仅是因为需要重写这两个方法就单独又造了一个类,这就让程序的侵入性变大。

侵入性是软件设计中需要重点考虑的因素,合理的低侵入性设计可以显著提高软件的可维护性、可扩展性和稳定性。

http://www.dtcms.com/a/329504.html

相关文章:

  • rtmp 推流
  • 浅层神经网络
  • Dimensional Analysis量纲分析入门
  • 猫粮哪个牌子质量好性价比高?2025适合幼猫的猫粮推荐
  • LangGraph 指南篇-基础控制
  • GaussDB 动态内存过高处理办法
  • 从表单校验到API网关:全链路输入安全防护指南
  • SeaTunnel MCP Server 入选《中国信通院开源商业产品及企业典型案例集(2025)》
  • 开源日志log4cplus—如何将 string类型转为tstring类型,又如何将char*类型转换为tstring类型?
  • 机器学习入门:核心概念详解与Python示例代码
  • 飞算JavaAI的“盾牌”计划:手撕Spring Security + JWT认证链
  • 【debian系统】cuda13和cudnn9.12详细安装步骤
  • 常用机器学习公开数据集大全
  • Spring、Spring MVC、Spring Boot与Spring Cloud的扩展点全面梳理
  • model层实现:
  • 设计模式笔记_行为型_策略模式
  • 【前端Vue】使用ElementUI实现表单中可选择可编辑的下拉框
  • 用 Qt C++ 从零打通“前端界面 → 后端接口”的数据交互
  • 为什么 sim(3) 中的尺度 s 与旋转 R 相乘,而不是平移 t?
  • Go语言实战案例:使用Gin处理路由参数和查询参数
  • 商品分类拖拽排序设计
  • Vue 3 快速入门 第七章
  • 第三天-经典CAN2.0 DBC快速切换为CANFD DBC
  • day39_2025-08-13
  • 手动编译 JSONCPP 静态库​(CMake)
  • aliases 的意义和作用?
  • Mac M1探索AnythingLLM+SearXNG
  • nginx配置代理服务器
  • (50)QT 绘图里,视图 QGraphicsView、场景 QGraphicsScene 及图形项 QGraphicsRectItem 的举例
  • gunicorn + flask 处理高并发请求