asp验证码bmp图片的生成原理

载入中
雨[http://www.yz81.com]11740哲提示:代码片段
<%
'------ access911.net 开发验证码图片 --------
'以下是方法原理演示,并没有做最优化,请大家自己看吧,解释绝对够详细了,
'你不需要有 BMP 图片的知识都可以看懂'如果你要自定义图片,只要在MYCODE中建立对应的文件夹,比如 mycode\w15h15;
'然后在其中用 WINDOWS 自己带的画图软件建立11张BMP图片,
'按规定定义图片名称即可,0-9 可定义为 0.BMP .... 9.BMP;
'最终要显示在客户端界面的 BMP 图片的大小应该定义为 displaysize.bmp;
'注意 0-9.BMP 与 DISPLAYSIZE.BMP 的高度和宽度要配合
'displaysize.BMP的底色就是杂点的颜色
Option Explicit
Response.buffer=true
NumCodeFunction NumCode()
Response.Expires = -1
Response.AddHeader "Pragma","no-cache"
Response.AddHeader "cache-ctrol","no-cache"
On Error Resume Next
Dim strNumber,i,j
Dim adoStream,adoStream1,adoStream2
dim CodeLen
dim fld
Dim intImg(),strAll
dim lngZ '杂点的百分比
dim x1,x2,x3(2)
Dim Pos '文件头的长度,一般固定为 54
dim w,h,w1,w0,h0pos=54 '文件头的长度,一般固定为 54
lngZ=2 '杂点比率是 1%
'对应文件的目录,长宽不同的BMP图片放在不同目录
fld = "w30h20" 'w宽度,h高度
Set adoStream=Server.CreateObject("Adodb.Stream")
adoStream.Mode=3
adoStream.Type=1
adoStream.Open
Set adoStream1=Server.CreateObject("Adodb.Stream")
adoStream1.Mode=3
adoStream1.Type=1
adoStream1.Open
Set adoStream2=Server.CreateObject("Adodb.Stream")
adoStream2.Mode=3
adoStream2.Type=1
adoStream2.Open
adoStream2.LoadFromFile(Server.mappath("mycode/" & fld & "/displaysize.bmp"))
if err<>0 then
response.Write server.HTMLEncode(err.number & err.Description)
response.End
end if
'displaysize.bmp 是你自己定义的显示的 BMP 的大小,我们只要取他的前54个字节
'adoStream2中存储了头字节'bmp图像头信息中,&H12 的四个字节代表宽 &H16 的四个字节代表高
adoStream2.position= &H12 '3+15 18个字节开始
w=adoStream2.read(4) '宽
h=adoStream2.read(4) '高
w=binval(w) '显示时候的总宽度
h=binval(h)
adoStream2.Position =0adoStream.LoadFromFile(Server.mappath("mycode/" & fld & "/0.bmp"))
if err<>0 then
response.Write server.HTMLEncode(err.number & err.Description)
response.End
end if
adoStream.position = &H12
w0=adoStream.read(4) '宽
h0=adoStream.read(4) '高
w0=binval(w0) '显示时候的总宽度
h0=binval(h0)'显示验证码图片的总宽度是每个图片的公倍数,并且显示验证码图片高度与每个数字图片高度一致
if w mod w0 = 0 and h = h0 then
'验证码由 N 个字构成,可更改,但是注意要与 displaysize.bmp配合
CodeLen= clng(w/w0)
else
response.write "显示图片宽度与数字图片宽度不符合或高度不符,请用画图软件重新编辑"
response.end
end ifw1=clng(w/CodeLen) '每个图片的宽度
Randomize timer
'strNumber = clng(8999*Rnd+1000)
'指定范围取随机整数 Int((upperbound - lowerbound + 1) * RND + lowerbound)
for i=1 to CodeLen
strNumber=strNumber & cstr(Int((9 - 0 + 1) * RND + 0))
next
Session("GetCode") = left(strNumber,CodeLen)
strAll=strNumber
redim intImg(CodeLen)
For i=0 To CodeLen-1
'以下代码用于调试,可以删除
'response.write "d" & i & "d" & mid(strAll,i+1,1) & "<br>"
intImg(i)=cint(mid(strAll,i+1,1))
Nextfor i=0 to CodeLen-1
adoStream.LoadFromFile(Server.mappath("mycode/" & fld & "/" & intImg(i) &".bmp"))
'以下代码用于调试,可以删除
'adostream.Position =0
'response.Write lenb(adostream.Read())
'response.End
'调试结束
'开始做杂点
for x2=1 to w1*h/100*lngZ
Randomize timer
x1=clng(clng((w1*h) - 0 + 1) * RND + 0) '随机取某个像素
if (pos+x1*3) < (w1*h*3+pos) then
adoStream.Position = (pos + x1*3)
end if
'注意,displaysize.BMP的底色就是杂点的颜色
adoStream2.Position =54
adoStream.Write adoStream2.Read(3)
next
'杂点结束
adoStream.position=54 '偏移到第54个字节,也就是图像矩阵开始的地方
adoStream1.write adoStream.read() '读取第54个字节到最后
next
'现在为止, adoStream1中存储了所有图像,不过是竖的
adostream1.Position =0
'以下代码用于调试,可以删除
'response.Write LENB(adostream1.read()) & "<BR>"
'response.End
'调试结束adoStream2.Position =0
'这里要进行行列转换
'如果是20像素*20像素,竖排,每像素1200/20/20=3个字节,每行20*3=60字节
DIM x,t1,t2,t3
For i=0 To h-1 Step 1 '高度是几个像素
For j=0 To CodeLen-1 'j代表有几个验证码字符
'如果是20*20像素,第一个图片的第一行,就应该停在0,第二个图片应该停在 1200字节上,第二行第一个图片时应该,60,第二行第二个图片应该是J*1200+i*60
'adoStream1.Position=i*60+j*1200 '固定大小:20*20
'adoStream1.Position=i*60+j*1800 '固定大小:20*20
'adoStream2.Position=Pos+60*j+i*360 '固定大小:20*20
'adoStream2.write adoStream1.read(60) '固定大小:20*20'adoStream1.Position=i*w1*3+j*w1*h*3
'由于扫描时,每一行必须是4的公倍数,因此上面这行由下面这段 IF 代替
IF (w1*3) MOD 4 <>0 THEN
FOR X = 1 TO 20
if (w1*3+X) MOD 4 = 0 then
exit for
end if
NEXT
t1=i*(w1*3+x)
t2=j*(w1*3+x)*h
'以下代码用于调试,可以删除
'RESPONSE.Write "I:" & i & " J:" & J & " W1:" & w1 & "--" & T2+T1 & "<BR>"
adoStream1.Position =t1+t2
'以下这句被前面那句 T1+T2 代替
'adoStream1.Position=i*(w/CodeLen*3+x)+j*(w/CodeLen*3+x)*h
ELSE
'动态:w/CodeLen 是宽度,w/CodeLen*h 是整个图片的大小,每过一个J,就是条转到下一个图片的相同位置
adoStream1.Position=i*w1*3+j*w1*h*3
END IF
'动态:w/CodeLen*3 是宽度,高度是第I行的整个字节长度 w/CodeLen*3*4
'adoStream2.Position=Pos+w1*3*j+i*w*3
'由于扫描时,每一行必须是4的公倍数,因此上面这行由下面这段 IF 代替
if (w*3) mod 4 <> 0 then
FOR X = 1 TO 20
if (w*3+x) MOD 4 = 0 then
exit for
end if
NEXT
adoStream2.Position=Pos+w1*3*j+i*(w*3+x)
else
'动态:w/CodeLen*3 是宽度,高度是第I行的整个字节长度 w/CodeLen*3*4
adoStream2.Position=Pos+w1*3*j+i*w*3
end if
'动态:
adoStream2.write adoStream1.read(w1*3)
Next
NextResponse.ContentType = "image/BMP"
adoStream2.Position=0
'这里是组成好整个 BMP 以后再输出,你完全可以一面组织一面输出给客户端。
'杂点也可以直接在输出的时候完成。
Response.BinaryWrite adoStream2.read()
adoStream.Close
adoStream1.Close
adoStream2.Close
set adoStream=nothing
set adoStream1=nothing
set adoStream2=nothing
If Err Then Session("GetCode") = err.description & 9999
End FunctionPublic Function BinVal(byval Bin)
Dim Ret, I
Ret = 0
For I = LenB(Bin) To 1 Step -1
Ret = Ret * 256 + AscB(MidB(Bin, I, 1))
Next
BinVal = Ret
End Function'------ access911.net 测试用 --------
%>
给文章部分内容增加权限[类似论坛购买贴][11-09]
留言本仿论坛模板及部分功能[11-08]
雨哲自定义表单系统 For SiteWeaver[11-07]
在线支付模板管理[11-07]
全站搜索 For SiteWeaver 通用[11-07]
企业会员展示系统[11-07]- 用户信息中心
- 与本文章相关内容
-
- >> [雨缘博客]雨哲自定义表单系统 For Si [日期:2008-11-07 03:03:03]
- >> [文章教程]ASP读取XML数据文件的方法 [日期:2008-08-14 00:52:26]
- >> [文章教程]网站后台安全的又一点做法— [日期:2008-07-07 00:39:18]
- >> [文章教程]ASP中常见数学函数Abs Int [日期:2008-07-07 00:07:53]
- >> [文章教程]asp关键字函数运算附 [日期:2008-07-04 16:23:37]
- >> [文章教程]ASP模板引擎代码 [日期:2008-06-29 06:50:05]
- >> [文章教程]Access内置函数 [日期:2008-04-10 01:14:49]
- >> [文章教程]使用ASP加密算法加密你的数 [日期:2008-04-07 09:43:56]
- >> [文章教程]使用ASP加密算法加密你的数 [日期:2008-04-07 09:41:43]
- >> [文章教程]用Asp读取数据库中数据到数 [日期:2008-03-25 14:47:45]
- 热门排行TOP10
-
- 1WORD 页眉设置 技巧 (3869)
- 2在线播放FLV格式文件 (3529)
- 3关于动易会员中心模 (3230)
- 4雨哲增强SiteWeaver (3114)
- 5无限级树型栏目导航 (2695)
- 6xxmrxut.exe病毒的手 (2225)
- 7小谈关于动易聚合空 (2163)
- 8完美CSS控制图片大小 (2067)
- 9如何在静态HTML页面 (2038)
- 10WindowsServerServi (1857)
- 推荐排行TOP10
-
- 1在线播放FLV格式文件 (3529)
- 2在网页右下角添加书 (1730)
- 3[ASP]隐藏文件下载地 (1575)
- 4雨哲浅谈关于防采集 (1403)
- 5一段asp高亮关键字代 (1362)
- 6在文字前加上与文字 (1254)
- 7文字自动适应Table( (1243)
- 8自定义标签设置搜索 (1238)
- 9[雨哲]关于增强会员 (1237)
- 10ASP 程序实现自动升 (1229)
