制作验证码的方法

首先你要明白24bit的bmp图片的基本信息:1像素占3个字节,头部占54个字节。
好了,现在开始做验证码了,这里以4位验证码(大小为20(高)*80(宽))为例子讲解。
1.用做图软件做两个图片,分别保存为24bit的bmp,
一个是20(高)*80(宽)的图片(yzmTmp.bmp),里面的数字随便,就是做出你要在网页上显示的验证码的样子。如图:

一个是20(高)*200(宽)的图片(yzm.bmp),里面的数字按1,2,3,4,5,6,7,8,9,0从左到右一次排列,每个数字在20*20的范围中居中放置。如图:

当然,里面的背景,字体及颜色你自己可随意设置。
2.用16进制编辑器(我用的是winhex)打开yzmTmp.bmp,只保留文件头部,就是把54字节后的所有内容删除。从最后开始删,这样容易保证只留下54字节的头文件。如图:

右边红色椭圆框显示54 bytes,接着另存为head.fix。
3.剩下的就是代码了
程序代码 程序代码

<%
Response.buffer = true
NumCode
Function NumCode()
Response.Expires = -1
Response.AddHeader "Pragma","no-cache"
Response.AddHeader "cache-ctrol","no-cache"
dim zNum,i,j
dim Ados,Ados1
Randomize timer
'生成随机四位数字:
zNum = cint(8999*Rnd+1000)
'传递给session
Session("GetCode") = zNum
'该for循环是将随机数字放入一个下标3的数组,便于提供给后面的阵列变换
dim zimg(3),NStr
NStr=cstr(zNum)
For i=0 to 3
zimg(i)=cint(mid(NStr,i+1,1))
Next
dim Pos
'’定义二个 ADODB.Stream binary对象,作图像数据操作之用:
set Ados=Server.CreateObject("Adodb.Stream")
Ados.Mode=3
Ados.Type=1
Ados.Open
set Ados1=Server.CreateObject("Adodb.Stream")
Ados1.Mode=3
Ados1.Type=1
Ados1.Open

Ados.LoadFromFile(Server.mappath("yzm.bmp"))
Ados1.write Ados.read(4800)

for ii=0 to 3
for j=0 to 19
    if zimg(ii)=0 then zimg(ii)=10 end if
    Ados.position=(zimg(ii)-1)*60+600*j+54
    Ados1.write ados.read(60)
next
next

'’清空已经用完的ADOS的数据,调入替换新的图像头54字节的头文件
Ados.LoadFromFile(Server.mappath("head.fix"))
Pos=lenb(Ados.read())
Ados.Position=Pos

Ados1.position=0
Ados.write ados1.read()


Ados.Position=0
'直接向客户端发送图像数据
Response.ContentType = "image/BMP"
Response.BinaryWrite Ados.read()
Ados.Close:set Ados=nothing
Ados1.Close:set Ados1=nothing
End Function
%>

4.在需要显示验证码的地方放如下代码就可以了
程序代码 程序代码
<img src="getYzm.asp" width="80" height="20" />


到此验证码就完成了,代码就不用解释了吧,不明白就看看adodb.stream方面的资料,我这只解释一下一些数字怎么来的,就是不明白照这套就可以了:
for ii=0 to 3
for j=0 to 19
    if zimg(ii)=0 then zimg(ii)=10 end if
    Ados.position=(zimg(ii)-1)*60+600*j+54
    Ados1.write ados.read(60)
next
nex

60    一个字节3个像素,每个数字是20×20,60就是指横着的20个像素占60个字节
600  整个图片是200像素宽,600就是指横着的200个像素占600个字节
240  生成的验证码为20×80,240就是指横着的80个像素占240个字节
54自然就是头的大小了。

最后看看演示

有了这个思路你就可以做各种各样的验证码,比如数字和字母验证码,汉字验证码了...不过这部分代码就要好好斟酌修改下了
程序代码 程序代码

Randomize timer
'生成随机四位数字:
zNum = cint(8999*Rnd+1000)
'传递给session
Session("GetCode") = zNum
'该for循环是将随机数字放入一个下标3的数组,便于提供给后面的阵列变换
dim zimg(3),NStr
NStr=cstr(zNum)
For i=0 to 3
zimg(i)=cint(mid(NStr,i+1,1))
Next


就说到这了,欢迎各位赐教,交流验证码的做法!!

验证码代码下载


[本日志由 亮亮 于 2009-02-24 11:07 PM 编辑]
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: 制作验证码
评论: 6 | 引用: 0 | 查看次数: -
回复回复亮亮[2009-06-12 01:04 PM | del]
最主要的是安全性,把生成的字符转化为图片,一般就需要人看才知道是什么,而按你这样写程序可以直接读取。
回复回复javen[2009-06-11 11:47 PM | del]
这个回复框限制了字数,我只能两次回复了,而且数组也删除了些字符。
我一般是这种方式做验证码的,你的这个设计好像更专业,我的这个简单实现方法有什么弊端吗?如安全性?你设计这个主要有点是什么?
回复回复javen[2009-06-11 11:44 PM | del]
function ger_code(code_length) {
  var rand_aa="";
  var code=new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J",
  "K","L","M","N","O","y","z","!","@","#","$","%","&",
  "*","(",")","-","_","|","?","/");
  var code_Num=code.length;  //数组长度
  for(i=0;i<code_length;i++)
   {
     var ran_ss=parseInt(Math.random()*code_Num);
    rand_aa+=String(code[ran_ss]);
   }
document.write("&nbsp;验证码&nbsp;<input type=text name=check_code size="+code_length+" value="+rand_aa+" class=blank_bg maxsize=5 readonly=true>");
}
回复回复qq5865455[2009-03-22 01:09 PM | del]
我到是想问你一下呀,验证码具体怎么使用呢,关键是判断输入验证码是否正确,正确后才能提交表单,比如一个留言版,输入验证码正确时在才能留言,不正确就提示验证码错误,在点提交按钮的时候判断验证码同时还插入记录,这种代码应该怎么写呀?我在百度搜了很多都看不懂他们说的意思,我看到过这样的一个说明:(、判断代码:
<%if trim(Server.HTMLEncode(Request.Form("yanzheng")))<>session("jd100_rn") then%>
)他只写了这么一句判断代码是什么 但具体怎么用我不知道啊?文本域应该怎么设置 提交按钮应该怎么设置   判断代码应该放在什么位置,    我看了很多都没弄明白  ,请大哥你帮帮我吧  教会我 QQ5865455 加上我呀。。。      就象我现在给你留言的一样,输入验证码点发表评论就成功     我就想做这样的。。
回复回复亮亮[2009-02-24 11:05 PM | del]
这跟图像的位置没有什么关系,我把代码打包放上面了,你自己下载看下!
回复回复崇拜你[2009-02-24 04:44 PM | del]
你好,我看了几遍你的验证码的制作,可是到了我这里怎么运行不了?你那个head.fix文件和两个BMP图像文件是存放在什么位置呢?
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.