美文网首页
如何用Java实现验证码?

如何用Java实现验证码?

作者: 源码时代官方 | 来源:发表于2020-09-01 10:59 被阅读0次

    验证码的出现在一定程度上降低了程序被攻击的风险,也使得我们的软件安全性得到有效提高。Java发展至今,网上也出现了各种各样的验证码:有图像验证码,字符验证码,还有用于计算的验证码等等。接下来为大家介绍几个原始验证码的写法。效果如下:

    |

    图片1.png 图片2.png

    [图片上传中...(图片3.png-889bd1-1598929100899-0)]

    第一款是基本的验证码,就背景颜色和字体颜色随机的。第二款是每个字符都是不同的颜色。第三款是每个字符都有不同的倾斜角度。

    验证码的实现原理:前端页面发送请求【使用<img>标签】到后端,后端使用io流写出一张图片,前端页面展示出来。前端代码如下:

    |

    验证码:<input name="code" style="width: 145px;vertical-align:middle"/>

    <img alt="" src="code" style="vertical-align:middle"

    onclick="this.src='code?r='+Math.random()">

    |

    接下来就是后台代码实现了,后台画一张图片实际上就跟美术生写生一样,先有一个画板,然后在画板上铺上一张宣纸,在使用画笔在宣纸上进行图像的绘制。

    图片4.png

    第一部分:获取画板对象,并设置绘画区域:

    |

    //=================================创建画板(缓存图片)=================================//

    //1.创建画板(缓存图片)(参数:宽度,高度,图像类型 -- 表示一个图像,该图像具有整数像素的 RGB 颜色)

    BufferedImage image= new BufferedImage(100, 30, BufferedImage.TYPE_INT_BGR);

    //2.根据缓冲图片获取一只画笔,默认颜色为白色

    Graphics g= image.getGraphics();

    //3.创建随机数对象,用于获取随机颜色

    Random r= new Random();

    //==================================画背景(随机颜色)==================================//

    //4.先给笔设置颜色,才能设置画的区域,范围在0~255

    //g.setColor(Color.gray);//设置固定颜色

    g.setColor(new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)));

    //5.在画板上设置画的区域(参数:0,0表示起点的x和y坐标,100表示宽度,30表示高度)

    g.fillRect(0, 0, 100, 30);

    |

    第二部分:画字符串(随机字符串,随机颜色,随机字体):

    |

    //6.获取随机字符串

    String string = getString(4);

    //7.为笔设置随机颜色,少了这一步的话,就会与背景颜色一样

    g.setColor(new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)));

    //8.为该字符串设置随机的字体

    g.setFont(getFont());

    //9.将字符串画出(参数:画的字符串,10,25指的是画字符串的x坐标和字符串基线坐标y)

    g.drawString(string, 10, 25);

    |

    第三部分:画干扰线和干扰点

    |

    //==========================画干扰线(随机位置)===========================//

    for(int i= 0 ; i< 4 ; i++){

    g.setColor(new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)));

    //参数:第一个点的坐标(x,y) 第二个点的坐标(x,y)

    //将笔强转成Graphics2D类型

    Graphics2D g1 = (Graphics2D)g;

    //然后设置笔为原始宽度的1.5倍,Stroke:画笔

    g1.setStroke(new BasicStroke(1.5f));

    g.drawLine(r.nextInt(100), r.nextInt(30), r.nextInt(100), r.nextInt(30));

    }

    //==========================画干扰点(随机位置)===========================//

    for(int i= 0 ; i< 20 ; i++){

    g.setColor(new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)));

    //参数:圆心坐标(x,y) 横轴长度 纵轴长度,Oval椭圆

    g.drawOval(r.nextInt(100), r.nextInt(30), 2, 2);

    }

    |

    第四部分:画出图片,释放资源

    |

    //============================将缓存图片写出去=============================//

    //x.设置响应的类型

    resp.setContentType("image/jpeg");

    //y.创建一个字节流(图片是二进制文件,只能通过字节流写出)

    ServletOutputStream os= resp.getOutputStream();

    //z.写出图片

    ImageIO.write(image, "jpeg", os);

    //关闭流释放资源

    os.close();

    |

    其他:自定义的方法:

    |

    //获取随机字符串

    public String getString(int num){

    //这里不写0,O,1,l,2,z,6,b,U,V,v,u,9,q是因为用于不好区分,提高用户体验度

    String words= "acdefghjkmnprstwxy34578ACEFGHJKLMNPQRSTWXY";

    String result= "";

    Random r= new Random();

    for(int i = 0;i< num;i++){

    result+= words.charAt(r.nextInt(words.length())) + " ";

    }

    return result;

    }

    //随机字体

    public Font getFont(){

    Font[] fonts= new Font[5];

    Random r= new Random();

    fonts[0] = new Font("微软雅黑", Font.ITALIC, 24);

    fonts[1] = new Font("新宋体", Font.PLAIN, 24);

    fonts[2] = new Font("Microsoft YaHei UI", Font.PLAIN, 24);

    fonts[3] = new Font("仿宋", Font.PLAIN, 24);

    fonts[4] = new Font("Cambria", Font.BOLD, 24);

    return fonts[r.nextInt(fonts.length)];

    }

    //随机颜色

    public Color getRandomColor() {

    Random ran= new Random();

    Color color= new Color(ran.nextInt(256),

                ran.nextInt(256), ran.nextInt(256));
    
        **return** color;
    
    }
    

    |

    实现不同字符的不同颜色:

    |

    StringBuilder <u>string</u>= new StringBuilder();

    int left = 10;

    for(int i= 0 ; i< 4 ; i++){

    g.setColor(getRandomColor());

    g.setFont(getFont());

    String words = getString(1);

    string.append(words);

    g.drawString(words, left, 25);

    left += 20;

    }

    |

    实现不同字符的不同旋转角度:

    |

    StringBuilder <u>string</u>= new StringBuilder();//接收验证码的字符串

    int <u>left</u> = 10;//设置画字符串的原始x坐标

    int x = 15;//设置字符串旋转的x坐标

    Random ran= new Random();

    for(int i= 0 ; i< 4 ; i++){

    g.setColor(getRandomColor());//随机颜色

    g.setFont(getFont());//随机字体

    String words = getString(1);//获取随机字符

    string.append(words);//拼接到字符串string

    Graphics2D g2 = (Graphics2D)g;//转换成Graphics2D对象,它才有rotate方法

    double th= ran.nextInt(100)/100.0;//随机旋转角度

    g2.rotate(th, x, 25);//旋转一个字符

    g2.drawString(words, left, 25);//画字符串

    g2.rotate(-th, x, 25);//调回原始角度

    left += 20;//继续画下一个字符

    x += 20;//继续旋转下一个字符

    }

    |

    相关文章

      网友评论

          本文标题:如何用Java实现验证码?

          本文链接:https://www.haomeiwen.com/subject/eoomsktx.html