在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在前一篇文章中初步的实现了验证码的随机生成,觉得很容易被破解,因此加了一些干扰; 鹤冲天建议使用表达式作为验证码,即使破解程序识别了验证码,也要计算结果才能通过验证,在一定程度上增加了破解难度。 因此我对代码进行了重新整理,通过控制运行时配置选项来达到不同效果。 现在主要做到了: (1)字符内容随机(普通字符串或表达式) (2)每个字符的字体随机 (3)每个字符大小随机 (4)每个字符倾斜角度随机 (5)干扰线条随机 除了(4)其他都可以通过配置来控制。 下面是代码,有详细的注释,就不多说了:
1 require("gd")
2 require("lfs") 3 4 ----------------------------------------------------------------------------------------------------------------------------------- 5 --运行配置项 6 ----------------------------------------------------------------------------------------------------------------------------------- 7 --字体:-1-使用gd.FONT_GIANT字体;1-使用随机字体;其他-使用“fonts”中第一个字体 8 --字体预先在变量“fonts”中定义;如果fonts没有值,将搜索系统中的所有字体,字体路径在“FONT_PATH”中预定义 9 FONT=1 10 11 --每个字符字体随机:1-是,其他-否 12 --仅当“FONT”值为“1”时,本变量起作用 13 FONT_RANDOM_CHAR=0 14 15 --每个字符字体大小是否随机:1-是,其他-否 16 --仅当FONT^=-1时起作用 17 FONT_SIZE_RANDOM=1 18 19 --是否增加线条干扰:1-是;其他-否 20 XLINE_FALG=1 21 22 --干扰线条的最多条数 23 --仅当“XLINE_FALG”的值为“是”是,本变量起作用 24 XLINE_LIMIT=6 25 26 --验证码类型:TEXT-字符串;EXPRESSION-表达式 27 MARK_TYPE="TEXT" 28 --MARK_TYPE="EXPRESSION" 29 30 --字符个数:仅当“MARK_TYPE”=“TEXT”时,本变量起作用 31 TEXT_NUM=6 32 33 --表达式项数限制(最多不超过EXPRESSION_ITEMS项):仅当“MARK_TYPE”=“EXPRESSION”时,本变量起作用 34 EXPRESSION_ITEMS=3 35 36 --生成验证码个数 37 MARK_NUM=100000 38 39 40 ----------------------------------------------------------------------------------------------------------------------------------- 41 --预定义变量 42 ----------------------------------------------------------------------------------------------------------------------------------- 43 --词典 44 dict={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0'} 45 numbers={"1","2","3","4","5","6","7","8","9"}--表达式可使用数字,排除0 46 operators={"+","-","*"}--表达式可使用运算符,不支持“/” 47 48 --随机种子,防止通过获取系统时间得到随机数种子,直接计算出验证码 49 math.randomseed(os.time()) 50 51 --大小 52 IMG_WIDTH=100 53 IMG_HEIGHT=40 54 55 --颜色 56 im2 = gd.createTrueColor(IMG_WIDTH,IMG_HEIGHT) 57 fg = im2:colorAllocate(129,32,28)--前景色 58 bg = im2:colorAllocate(216,235,238)--背景色 59 60 --字体 61 FONT_PATH="C:/WINDOWS/Fonts/"--系统字体路径 62 fonts={} 63 --fonts={"courbd.ttf","courbi.ttf","DejaVuMonoSans.ttf","DejaVuMonoSansBold.ttf","DejaVuMonoSansBoldOblique.ttf","DejaVuMonoSansOblique.ttf","lucon.ttf","monosbi.ttf","nina.ttf","simhei.ttf","simkai.ttf","swissci.ttf","tahomabd.ttf","timesbd.ttf","timesbi.ttf","timesi.ttf","trebuc.ttf","trebucit.ttf"} 64 font_size={14,15,16,17,18,19,20}--随机字体大小 65 66 --生成的随机码 67 stringmark="" 68 69 ----------------------------------------------------------------------------------------------------------------------------------- 70 --功能函数 71 ----------------------------------------------------------------------------------------------------------------------------------- 72 --初始化:创建图片、设置背景 73 function init() 74 im2 = gd.createTrueColor(IMG_WIDTH, IMG_HEIGHT) 75 im2:filledRectangle(0,0,IMG_WIDTH,IMG_HEIGHT,bg) 76 stringmark="" 77 end 78 79 --查找字体 80 function searchFont() 81 if table.getn(fonts)==0 then --没有指定字体,就搜索系统字体 82 local i=1 83 for file in lfs.dir(FONT_PATH) do 84 if string.find(file,".ttf")and not string.find(file,"esri") then --排除特定字体 85 fonts[i]=file 86 i=i+1 87 end 88 end 89 end 90 end 91 92 --生成text字符串 93 function makeText() 94 local num=table.getn(dict) 95 for i=1,TEXT_NUM do 96 stringmark=stringmark..dict[math.random(num)] 97 end 98 end 99 100 --生成表达式字符串 101 function makeExpression() 102 local n=math.random(2,3)--表达式项数 103 local strings={} 104 for i=1,n*2-1 do--表达式项数+运算符项数 105 local str="" 106 if i%2==1 then--数字 107 local n2=math.random(1,2) 108 for j=1,n2 do--每个数字最多2位 109 str=str..numbers[math.random(9)] 110 end 111 else--运算符 112 str=operators[math.random(3)] 113 end 114 strings[i]=str 115 end 116 return strings 117 end 118 119 --主函数 120 function doIt() 121 searchFont() 122 local numfonts=table.getn(fonts) 123 if numfonts<1 then 124 print("没有找到字体!") 125 return 126 end 127 128 for i=1,MARK_NUM do 129 init() 130 local font=fonts[0]; 131 local fontsize=20; 132 133 if MARK_TYPE=="TEXT" then--普通字符串验证码 134 makeText() 135 -- print(stringmark) 136 if FONT==-1 then 137 im2:string(gd.FONT_GIANT,18,10,stringmark, fg) 138 else 139 for nIndex=1,string.len(stringmark) do 140 if FONT==1 then font=fonts[math.random(numfonts)] end 141 if FONT_SIZE_RANDOM==1 then fontsize=font_size[math.random(7)] end 142 im2:stringFT(fg,FONT_PATH..font,fontsize,math.random()/math.pi,5+(nIndex-1)*15, 25, string.sub(stringmark,nIndex,nIndex)) 143 end 144 end 145 elseif MARK_TYPE=="EXPRESSION" then--表达式验证码 146 local strings=makeExpression() 147 local raise=0 148 local ncharacter=0 149 for j=1,table.getn(strings) do 150 if j%2==0 then raise=3 end 151 stringmark=stringmark..strings[j] 152 if FONT==1 then font=fonts[math.random(numfonts)] end 153 if FONT_SIZE_RANDOM==1 then fontsize=font_size[math.random(5)] end 154 im2:stringFT(fg,FONT_PATH..font,fontsize,math.random()/math.pi,5+ncharacter*12+raise, 25, strings[j]) 155 ncharacter=ncharacter+string.len(strings[j]) 156 end 157 -- print(stringmark) 158 -- value=tonumber(stringmark) 159 -- 全部评论
专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论