Randomize Dim i,ii,iii,flag,ActUnitWidth,ImgYuWidth,codeLen,ImgWidth,ImgHeight codeLen = codeLenMin + cint(Rnd*(codeLenMax-codeLenMin)) If ImgWidth Mod 4 <> 0 Or ImgWidth < codeLen*UnitWidth Then ImgWidth = codeLen*UnitWidth If ImgHeight < UnitHeight Then ImgHeight = UnitHeight
" 随机产生字符 Dim vCode(), vCodes ReDim vCode(codeLen-1) vCodes = GetVerifyNumber For i = 0 To 4 vCode(i) = cint(mid(vCodes,i+1,1)) vCode(i) = pcd_doubter(vNumberData(vCode(i)),UnitWidth,UnitHeight,DotsLimit,tryCount,dbtTimes) Next
" 位置随机 ActUnitWidth = Int(ImgWidth / codeLen) ImgYuWidth = ImgWidth - ActUnitWidth * codeLen ReDim posAry(1,codeLen-1) posAry(0,0) = Int((Rnd)*(posX+(ActUnitWidth-UnitWidth)/2)) posAry(1,0) = Int((ImgHeight-UnitHeight)/2+(1-2*Rnd)*posY) For i=1 To codeLen-2 posAry(0,i) = Int((1-2*Rnd)*(posX+(ActUnitWidth-UnitWidth)/2)) posAry(1,i) = Int((ImgHeight-UnitHeight)/2+(1-2*Rnd)*posY) Next If codeLen > 1 Then posAry(0,codeLen-1) = Int((Rnd)*(posX+(ActUnitWidth-UnitWidth)/2)) posAry(1,codeLen-1) = Int((ImgHeight-UnitHeight)/2+(-Rnd)*posY) End If
" 输出图像数据 For i = ImgHeight-1 To 0 Step -1 "行 For ii = 0 To codeLen-1 "字 For iii = 0 To ActUnitWidth-1 "字宽 flag = 0 If onNoiseLine(noiseLine,ii*ActUnitWidth+iii,i) Then " 干扰线 flag = 1 ElseIf getUnitDot(posAry,vCode,ii,iii,i,UnitWidth,UnitHeight) = "0" Then flag = 1 ElseIf getUnitDot(posAry,vCode,ii-1,iii+ActUnitWidth,i,UnitWidth,UnitHeight) = "0" Then flag = 1 ElseIf getUnitDot(posAry,vCode,ii+1,iii-ActUnitWidth,i,UnitWidth,UnitHeight) = "0" Then flag = 1 End If " 随机生成杂点 If Rnd * 99 + 1 < cOdds Then flag = 1 - flag Response.BinaryWrite vColorData(1-flag) Next Next For ii = 0 To ImgYuWidth-1 Response.BinaryWrite vColorData(1) Next Next End Sub
Rem 获取单元的点(考虑位移) Function getUnitDot(ByRef posAry,ByRef vCode,i,ByVal x,ByVal y,UnitWidth,UnitHeight) getUnitDot = "1" If i < 0 Or i > UBound(vCode) Then Exit Function x = x - posAry(0,i) If x < 0 Or x >= UnitWidth Then Exit Function y = y - posAry(1,i) If y < 0 Or y >= UnitHeight Then Exit Function getUnitDot = Mid(vCode(i),y*UnitWidth+x+1,1) End Function
Rem 生成干扰线 Sub makeNoise(ByRef nl,imgW,UnitHeight) Dim i,l,x1,y1,x2,y2,dx,dy,deltaT x1 = Int(Rnd*imgW) y1 = Int(Rnd*UnitHeight) x2 = Int(Rnd*imgW) y2 = Int(Rnd*UnitHeight) dx = X2 - X1 dy = Y2 - Y1 If Abs(dx) > Abs(dy) Then deltaT = Abs(dx) Else deltaT = Abs(dy) If deltaT = 0 Then Exit Sub l = UBound(nl,2) ReDim Preserve nl(1,l+deltaT+1) l = l + 1 For i = 0 To deltaT nl(0,l+i) = x1 + dx * i deltaT nl(1,l+i) = y1 + dy * i deltaT Next End Sub
Rem 判断是否为干扰线上的点 Function onNoiseLine(ByRef nl,x,y) onNoiseLine = False Dim i For i=0 To UBound(nl,2) If x = nl(0,i) And y = nl(1,i) Then onNoiseLine = True Exit For End If Next End Function
Rem 对单个字的点阵进行干扰 Rem 干扰思想:在点阵范围内随机产生2个端点,进行连线,以位移较大的一方做横轴,先将连线上的点删除,再将被删除点的纵轴方向上方或下方的点(随机确定)移向被删除点,移动后的空白用背景色补充 Function pcd_doubter(ByVal str,UnitWidth,UnitHeight,DotsLimit,tryCount,dbtTimes) Randomize Dim x1,x2,y1,y2,dx,dy,deltaT,i,ii,way,f1,f2 For f1=1 To dbtTimes "干扰次数 For f2=1 To tryCount "避免删除有效点超过上限的尝试次数限制 "随机确定2个端点 x1 = int(Rnd*UnitWidth) x2 = int(Rnd*UnitWidth) y1 = int(Rnd*UnitHeight) y2 = int(Rnd*UnitHeight) dx = X2 - X1 dy = Y2 - Y1 If Abs(dx) > Abs(dy) Then deltaT = Abs(dx) Else deltaT = Abs(dy) ReDim ary(1,deltaT) "存储连线的点 If deltaT = 0 Then ary(0,0) = x1 ary(1,0) = y1 Else ii = 0 For i = 0 To deltaT ary(0,i) = x1 + dx * i deltaT ary(1,i) = y1 + dy * i deltaT If pcd_getDot(ary(0,i),ary(1,i),str,UnitWidth) = "0" Then ii = ii + 1 Next " 统计连线上有效点的数量,如未超过有效点上限则跳出循环,执行干扰 If ii <= DotsLimit Then Exit For End If Next
" 执行干扰(dx,dy改作不同的方向标记用) If Abs(dx) > Abs(dy) Then dx = 1 Else dx = 0 If dx = 1 Then If Int(Rnd*10) > 4 Then dy = 1 way = -1 Else dy = UnitHeight - 2 way = 1 End If Else If Int(Rnd*10) > 4 Then dy = 1 way = -1 Else dy = UnitWidth - 2 way = 1 End If End If For i=0 To deltaT For ii=ary(dx,i) To dy Step way Call pcd_setDot(ary(0,i)*dx+ii*(1-dx),ary(1,i)*(1-dx)+ii*(dx),str,pcd_getDot(ary(0,i)*dx+(ii+way)*(1-dx),ary(1,i)*(1-dx)+(ii+way)*(dx),str,UnitWidth),UnitWidth) Next "添补空白 Call pcd_setDot(ary(0,i)*dx+(dy+way)*(1-dx),ary(1,i)*(1-dx)+(dy+way)*(dx),str,"1",UnitWidth) Next Next pcd_doubter = str End Function
Rem 得到某点的字符 Function pcd_getDot(x,y,str,UnitWidth) pcd_getDot = Mid(str,x+1+y*UnitWidth,1) End Function
Rem 设置某点的字符 Sub pcd_setDot(x,y,ByRef str,newDot,UnitWidth) str = Left(str,x+y*UnitWidth) & newDot & Right(str,Len(str)-x-y*UnitWidth-1) End Sub
Rem 将数字转为bmp需要的格式 lens是目标字节长度 Function Num2ChrB(ByVal num,lens) Dim ret,i ret = "" While (num>0) ret = ret & ChrB(num mod 256) num = num 256 WEnd For i=Lenb(ret) To lens-1 ret = ret & chrB(0) Next Num2ChrB = ret End Function %>