【登录验证码】动态与静态验证码实现逻辑

素颜马尾好姑娘i 2022-10-26 03:48 362阅读 0赞

目录

1、需要设计一个静态验证码实体类

随机生成字母数字的工具类

Captcha验证码类

动画gif实体类

验证码前端接口


前言

要实现一个静态的简单地字母数字的验证码登录,同时也实现一个划拉式的验证码动态匹配的实现逻辑;

1、需要设计一个静态验证码实体类

随机生成字母数字的工具类

  1. /**
  2. *随机工具类 作为一个随机生成字母数字的工具类
  3. * @version:1.0
  4. */
  5. public class Randoms
  6. {
  7. private static final Random RANDOM = new Random();
  8. //定义验证码字符.去除了O和I等容易混淆的字母
  9. public static final char ALPHA[]={'A','B','C','D','E','F','G','H','G','K','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'
  10. ,'a','b','c','d','e','f','g','h','i','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z','2','3','4','5','6','7','8','9'};
  11. /**
  12. * 产生两个数之间的随机数
  13. * @param min 小数
  14. * @param max 比min大的数
  15. * @return int 随机数字
  16. */
  17. public static int num(int min, int max)
  18. {
  19. return min + RANDOM.nextInt(max - min);
  20. }
  21. /**
  22. * 产生0--num的随机数,不包括num
  23. * @param num 数字
  24. * @return int 随机数字
  25. */
  26. public static int num(int num)
  27. {
  28. return RANDOM.nextInt(num);
  29. }
  30. public static char alpha()
  31. {
  32. return ALPHA[num(0, ALPHA.length)];
  33. }
  34. }

Captcha验证码类

  1. /**
  2. * 验证码抽象类,暂时不支持中文,目前仅仅支持随机的字母数字
  3. * @version:1.0
  4. */
  5. @Data
  6. public abstract class Captcha extends Randoms {
  7. /**
  8. * 字体
  9. */
  10. protected Font font = new Font("Verdana", Font.ITALIC | Font.BOLD, 28);
  11. // 验证码随机字符长度
  12. /**
  13. * 验证码随机字符长度
  14. */
  15. protected int len = 5;
  16. /**
  17. * 宽度
  18. */
  19. protected int width = 150;
  20. // 验证码显示高度
  21. /**
  22. * 高度
  23. */
  24. protected int height = 40;
  25. /**
  26. * 随机字符串
  27. */
  28. private String chars = null;
  29. /**
  30. * 生成随机字符数组
  31. *
  32. * @return 字符数组
  33. */
  34. protected char[] alphas() {
  35. char[] cs = new char[len];
  36. for (int i = 0; i < len; i++) {
  37. cs[i] = alpha();
  38. }
  39. chars = new String(cs);
  40. return cs;
  41. }
  42. /**
  43. * 给定范围获得随机颜色
  44. *
  45. * @return Color 随机颜色
  46. */
  47. protected Color color(int fc, int bc) {
  48. if (fc > INT_TWO_FIVE_FIVE) {
  49. fc = INT_TWO_FIVE_FIVE;
  50. }
  51. if (bc > INT_TWO_FIVE_FIVE) {
  52. bc = INT_TWO_FIVE_FIVE;
  53. }
  54. int r = fc + num(bc - fc);
  55. int g = fc + num(bc - fc);
  56. int b = fc + num(bc - fc);
  57. return new Color(r, g, b);
  58. }
  59. /**
  60. * 验证码输出,抽象方法,由子类实现
  61. *
  62. * @param os 输出流
  63. */
  64. public abstract void out(OutputStream os);
  65. /**
  66. * 获取随机字符串
  67. *
  68. * @return string
  69. */
  70. public String text() {
  71. return chars;
  72. }
  73. }
  74. /**
  75. * int常量
  76. */
  77. public static final int INT_ZERO = 0;
  78. public static final int INT_ONE = 1;
  79. public static final int INT_TWO = 2;
  80. public static final int INT_THREE = 3;
  81. public static final int INT_FIVE = 5;
  82. public static final int INT_SERVEN = 7;
  83. public static final int INT_TWO_FIVE_FIVE = 255;

动画gif实体类

  1. /**
  2. * <p>Gif验证码类</p>
  3. * @version:1.0
  4. */
  5. public class GifCaptcha extends Captcha
  6. {
  7. public GifCaptcha()
  8. {
  9. }
  10. public GifCaptcha(int width,int height){
  11. this.width = width;
  12. this.height = height;
  13. }
  14. public GifCaptcha(int width,int height,int len){
  15. this(width,height);
  16. this.len = len;
  17. }
  18. public GifCaptcha(int width,int height,int len,Font font)
  19. {
  20. this(width,height,len);
  21. this.font = font;
  22. }
  23. @Override
  24. public void out(OutputStream os)
  25. {
  26. try
  27. {
  28. // gif编码类,这个利用了洋人写的编码类,所有类都在附件中
  29. GifEncoder gifEncoder = new GifEncoder();
  30. //生成字符
  31. gifEncoder.start(os);
  32. gifEncoder.setQuality(180);
  33. gifEncoder.setDelay(100);
  34. gifEncoder.setRepeat(0);
  35. BufferedImage frame;
  36. char[] rands =alphas();
  37. Color fontcolor[]=new Color[len];
  38. for(int i=0;i<len;i++)
  39. {
  40. fontcolor[i]=new Color(20 + num(110), 20 + num(110), 20 + num(110));
  41. }
  42. for(int i=0;i<len;i++)
  43. {
  44. frame=graphicsImage(fontcolor, rands, i);
  45. gifEncoder.addFrame(frame);
  46. frame.flush();
  47. }
  48. gifEncoder.finish();
  49. }finally
  50. {
  51. try {
  52. os.close();
  53. } catch (IOException e) {
  54. // TODO Auto-generated catch block
  55. e.printStackTrace();
  56. }
  57. }
  58. }
  59. /**
  60. * 画随机码图
  61. * @param fontcolor 随机字体颜色
  62. * @param strs 字符数组
  63. * @param flag 透明度使用
  64. * @return BufferedImage
  65. */
  66. private BufferedImage graphicsImage(Color[] fontcolor,char[] strs,int flag)
  67. {
  68. BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
  69. //或得图形上下文
  70. //Graphics2D g2d=image.createGraphics();
  71. Graphics2D g2d = (Graphics2D)image.getGraphics();
  72. //利用指定颜色填充背景
  73. g2d.setColor(Color.WHITE);
  74. g2d.fillRect(0, 0, width, height);
  75. AlphaComposite ac3;
  76. int h = height - ((height - font.getSize()) >>1) ;
  77. int w = width/len;
  78. g2d.setFont(font);
  79. for(int i=0;i<len;i++)
  80. {
  81. ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
  82. g2d.setComposite(ac3);
  83. g2d.setColor(fontcolor[i]);
  84. g2d.drawOval(num(width), num(height), 5+num(10), 5+num(10));
  85. g2d.drawString(strs[i]+"", (width-(len-i)*w)+(w-font.getSize())+1, h-4);
  86. }
  87. g2d.dispose();
  88. return image;
  89. }
  90. /**
  91. * 获取透明度,从0到1,自动计算步长
  92. * @return float 透明度
  93. */
  94. private float getAlpha(int i,int j)
  95. {
  96. int num = i+j;
  97. float r = (float)1/len,s = (len+1) * r;
  98. return num > len ? (num *r - s) : num * r;
  99. }
  100. }

验证码前端接口

  1. @Autowired
  2. private ZaptchaProperties captchaProperties;
  3. @Autowired
  4. private Producer producer;
  5. @Autowired
  6. private RedisUtil redisUtil;
  7. /**
  8. * 生成gif验证码
  9. */
  10. @RequestMapping("/gif")
  11. public void indexGif(HttpServletRequest request, HttpServletResponse response) {
  12. String captchaId = request.getParameter("captchaId");
  13. if (ToolUtil.isEmpty(captchaId)) {
  14. throw new ServiceException(ExceptionEnum.REQUEST_NULL);
  15. }
  16. Captcha gifCaptcha = new GifCaptcha(captchaProperties.getCaptchaWidth(),
  17. captchaProperties.getCaptchaHigh(),
  18. captchaProperties.getCaptchaLen());
  19. response.setDateHeader("Expires", 0);
  20. // Set standard HTTP/1.1 no-cache headers.
  21. response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
  22. // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
  23. response.addHeader("Cache-Control", "post-check=0, pre-check=0");
  24. // Set standard HTTP/1.0 no-cache header.
  25. response.setHeader("Pragma", "no-cache");
  26. // return a jpeg
  27. response.setContentType("image/gif");
  28. //输出
  29. //存入Session
  30. OutputStream out = null;
  31. try {
  32. out = response.getOutputStream();
  33. gifCaptcha.out(out);
  34. redisUtil.set(captchaProperties.getCaptchaSessionKey() + captchaId, gifCaptcha.text().toLowerCase(), captchaProperties.getCaptchaSessionExpired());
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. } finally {
  38. if (out != null) {
  39. try {
  40. out.close();
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }
  46. }
  47. /**
  48. * 生成普通验证码
  49. */
  50. @RequestMapping("pic")
  51. public void indexPic(HttpServletRequest request, HttpServletResponse response) {
  52. String captchaId = request.getParameter("captchaId");
  53. if (ToolUtil.isEmpty(captchaId)) {
  54. throw new ServiceException(ExceptionEnum.REQUEST_NULL);
  55. }
  56. response.setDateHeader("Expires", 0);
  57. // Set standard HTTP/1.1 no-cache headers.
  58. response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
  59. // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
  60. response.addHeader("Cache-Control", "post-check=0, pre-check=0");
  61. // Set standard HTTP/1.0 no-cache header.
  62. response.setHeader("Pragma", "no-cache");
  63. // return a jpeg
  64. response.setContentType("image/jpeg");
  65. // create the text for the image
  66. String capText = producer.createText();
  67. // create the image with the text
  68. BufferedImage bi = producer.createImage(capText);
  69. ServletOutputStream out = null;
  70. try {
  71. out = response.getOutputStream();
  72. } catch (IOException e) {
  73. e.printStackTrace();
  74. }
  75. // write the data out
  76. try {
  77. ImageIO.write(bi, "jpg", out);
  78. redisUtil.set(captchaProperties.getCaptchaSessionKey() + captchaId, capText.toLowerCase(), captchaProperties.getCaptchaSessionExpired());
  79. } catch (IOException e) {
  80. e.printStackTrace();
  81. }
  82. try {
  83. try {
  84. out.flush();
  85. } catch (IOException e) {
  86. e.printStackTrace();
  87. }
  88. } finally {
  89. try {
  90. out.close();
  91. } catch (IOException e) {
  92. e.printStackTrace();
  93. }
  94. }
  95. }
  96. }

发表评论

表情:
评论列表 (有 0 条评论,362人围观)

还没有评论,来说两句吧...

相关阅读

    相关 登录验证

    验证码的作用是区分人与机器,防止机器刷数据; 验证码的验证分了两步,一步是请求获取验证码,一步是前台传的验证码与后台的验证码进行对比判断后进行后续操作; 在MyEclips

    相关 springMVC--动态验证实现

    在网站开发过程中我们一般都会为了防止用户连续提交都会提供验证码的功能,简单来说就是生成一个动态图片,在图片中保存一些校验信息,将校验信息放到session中和用户提交的验证码信

    相关 登录验证实现

    前言: 验证码,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的