Java生成中文验证码

 

1980,为了使每一个汉字有一个全国统一的编码,我国制定了”中华人民共和国国家标准信息交换汉字编码”,标准代号为GB2312-80,这种编码又称为国标码,国标码字符集中共收录了一级汉字3755,二级汉字3008,图形符号682,3项字符总计7445.

国标GB2312-80中规定,所有的国标汉字及符号分配在一个94,94列的方阵中,方阵的每一个行称为一个”区”,编号为01-94,每一个列称为一个”位”,编号为01-94,方阵中的每一个汉字和符号所在的区号和位号组合在一起形成的4个阿拉伯数字就是他们的”区位码”,区位码的前两位是它的区号,后两位是它的位号,用区位码就可以唯一的确定一个汉字或符号,反之,任何一个汉字或符号也都对应一个唯一的区位码.

所有的汉字和符号所在的区 分为以下4个组.

1). 01-15,图形符号,其中01-09区分标准符号区,10-15区为自定义符号区

2). 16-55一级常用汉字区,包括3755个一统汉字.40个区中的汉字是按汉语拼音排序的.同音字按笔划顺序排序.其中55区的90-94位未定义汉字

3). 56-87二级汉字区,包括3008个二级汉字,按部首排序

4). 89-94,自定义汉字区

其中,10-15区的自定义符号区和第88-94区的自定义符号区可由用户自定义,国标码中未定义的符号和汉字.

与汉字的区位码类似的还有汉字机内码,它是在汉字区位码的区码和位码上分别加上A0H(这里的H表示前两位数字为16进制数)而得到的,使用机内码表示的一个汉字占用2个字节,分别称为高位字节和低位字节.这两位字节的机内码按一下规则表示:

高位字节=区码+20H+80H(或区码+A0H),

低位字节=位码+20H+80H(或位码+A0H),

例如,汉字”啊”的区位码为1601,区码和位码分别用16进制表示即为1001H.它的机内码的高位字节为B0H,低位字节为A1H.机内码就是B0A1H.

 

实例截图

Java生成中文验证码

前端代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <title>中文验证码</title>

    <link href="css2/css.css" rel="stylesheet" type="text/css" />

    <style type="text/css"> table { width:560px; border-collapse:collapse; /* 合并单元格之间的边 */ border:1px solid #0099aa; font:normal 12px/1.5em "宋体", Verdana,Lucida, Arial, Helvetica, sans-serif;

        } /* 定义表格的整体宽度以及边框样式,并且定义表格内所有文字的样式 */

    

    </style>

    <script type="text/javascript">

        function changeCode(){ document.getElementById("imgcode").src="checkCode?nocache="+new Date().getTime(); } </script>

  </head>

  

  <body onload="checkCode">

        <form id="regist" method="post" >    

        <table align="center" border="1" bordercolor="#0099aa">

            

            <tr>

                <td align="right" width="130px">用户名:</td>

                <td >

                    <input type="text" name="name" id="name" />

                    <font color="red">* 用户名由字母数字和下划线组成</font>

                </td>

            </tr>



            <tr>

                <td align="right">验证码:</td>

                <td >

                    <img title="看不清,点击更换验证码" style="cursor:pointer" id="imgcode" alt="" src="checkCode" onclick="changeCode()" >

                </td>

            </tr>

            <tr>

                <td align="right">输入验证码:</td>

                <td><input type="text" name="code" id="code" /></td>

            </tr>

            <tr>

                <td></td>

                <td>

                    <input type="submit" value="注 册"/>&nbsp;&nbsp;

                    <input type="reset" value="重 置" />

                </td>

                

            </tr>

        </table>

    </form>

  </body>

</html>

xml中配置

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <servlet>

    <servlet-name>ChineseCheckCode</servlet-name>

    <servlet-class>com.webapp.service.ChineseCheckCode</servlet-class>

  </servlet>



  <servlet-mapping>

    <servlet-name>ChineseCheckCode</servlet-name>

    <url-pattern>/checkCode</url-pattern>

  </servlet-mapping>

  

  <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

</web-app>

服务端生成文字验证码,需要使用 response.setContentType("image/jpeg");指定生成的响应是图片

 

package com.webapp.service; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * * ChineseCheckCode.java * * @version : 1.1 * * @author : 苏若年 <a href="mailto:[email protected]">发送邮件</a> * * @since : 1.0 创建时间: 2013-2-13 下午06:45:59 * * TODO : class ChineseCheckCode.java is used for ... * */

public class ChineseCheckCode extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //禁止缓存

        response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "No-cache"); response.setDateHeader("Expires", 0); // 指定生成的响应是图片

        response.setContentType("image/jpeg"); int width = 155;      //指定验证码的宽度

        int height = 45;      //指定验证码的高度

        BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB); Graphics graphics = image.getGraphics();      //获取Graphics类的对象

        Random random = new Random();          //实例化一个Random对象

        Font mFont = new Font("宋体", Font.ITALIC, 26);   //通过Font构造字体

        graphics.setColor(getRandomColor(200, 250)); //设置颜色

        graphics.fillRect(0, 0, width, height); graphics.setFont(mFont); //设置字体

        graphics.setColor(getRandomColor(180, 200)); //设置文字的颜色

 String chckcode = ""; String ctmp = ""; for(int i=0; i<4; i++){ String[] rBase = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; //生成第一位的区码

            int rand1 = random.nextInt(3)+11;    //生成11到14之间的随机数

            String strR1 = rBase[rand1]; //生成第二位的区码

            int rand2 ; if(rand1 == 13){ rand2 = random.nextInt(7);        //生成0-7之间的随机数

            }else{ rand2 = random.nextInt(16);        //生成0-16之间的随机数

 } String strR2 = rBase[rand2]; //生成第一位的位码

            int rand3 = random.nextInt(15)+1;    //生成1到16之间的随即数

            String strR3 = rBase[rand3]; //生成第二位的位吗

            int rand4; if(rand3==10){ rand4 = random.nextInt(15)+1;    //生成1到16之间的随机数

            }else if(rand3==15){ rand4 = random.nextInt(15);        //生成0到15之间的随机数

            }else{ rand4 = random.nextInt(16);        //生成0到16之间的随机数

 } String strR4 = rBase[rand4]; //将生成的机内码转换为汉字

            byte[] bytes = new byte[2]; //将生成的区码保存到字节数组的第一个元素中

            String strR12 = strR1 + strR2; int tempLow = Integer.parseInt(strR12, 16); bytes[0] = (byte) tempLow; String strR34 = strR3 + strR4; int tempHigh = Integer.parseInt(strR34, 16); bytes[1] = (byte) tempHigh; ctmp = new String(bytes);            //根据字节数组生成汉字

            chckcode = chckcode + ctmp; Color color = new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)); graphics.setColor(color); /** **随机缩放文字并将文字旋转指定角度* */ Graphics2D graphics2d = (Graphics2D) graphics; //实例化AffineTransform类的对象

            AffineTransform trans = new AffineTransform(); //进行旋转

            trans.rotate(random.nextInt(25) * 3.14 / 180, 26 * i + 8, 7); // 缩放文字

            float scaleSize = random.nextFloat() +0.7f; if (scaleSize > 1f) scaleSize = 1f; trans.scale(scaleSize, scaleSize); //进行缩放

 graphics2d.setTransform(trans); graphics.drawString(ctmp, width/6 * i+30, height/3+5); } //将生成的验证码保存到Session中

        HttpSession session = request.getSession(true); session.setAttribute("chckcode", chckcode); graphics.dispose(); ImageIO.write(image, "JPEG", response.getOutputStream()); } /** * 生成随即颜色 * @param fc * @param bc * @return

     */

    public Color getRandomColor(int fc, int bc){ Random random = new Random(); Color randomColor = null; if(fc>255) fc=255; if(bc>255) bc=255; //设置个0-255之间的随机颜色值

        int r=fc+random.nextInt(bc-fc); int g=fc+random.nextInt(bc-fc); int b=fc+random.nextInt(bc-fc); randomColor = new Color(r,g,b); return randomColor;//返回具有指定红色、绿色和蓝色值的不透明的 sRGB 颜色

 } }

 

转载请注明出处:[http://www.cnblogs.com/dennisit/archive/2013/02/16/2913263.html]

在线交谈

你可能感兴趣的:(java)