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.
实例截图
前端代码
<%@ 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="注 册"/>
<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]