| Hui 的个人资料热带鱼-热的带鱼照片日志列表 | 帮助 |
|
2007/3/23 感谢stone谢谢石头一直以来对鱼我的关心.
在黑暗的7月里给俺开导
在考研的日子里给俺鼓励~
在考研后的日子里给按照顾~~
在准备复试的日子里还把她心爱的mp4 借俺让按准备英语听力~~~
谢谢石头~~~~
俺会好好努力哈~~~
等俺好消息~
俺也有信心~
也许该给自己忙碌忙碌了下周开始
如果顺利
将开始一周7天的忙碌日子
5天去动物园公交枢纽站工作
剩下2天准备复试和毕设
这样的日子一直得持续到这个学期结束
也许还是忙碌点好,这样生活就充实了
fighting......
fighting.......
鱼,加把劲
不要让人失望~~~ 2007/3/19 [转载]男人的痛,女人不懂--停不了的爱※1、女人永远也不知道男人为什么要学会坚强?
因为他们自己知道.他们虽然外表坚强.但内心很脆弱.他们永远想让自己身边的她觉得自己是最棒的. ☆2、女人永远也不知道男人为什么不会轻易掉眼泪?
因为他们自己知道.他们不是不会掉眼泪.只是他明白.一但眼泪掉下来了.这段感情也就结束了. △3、女人永远也不知道男人为什么每次在心烦的时候那么喜欢抽烟?
因为他们自己知道.只有在烟雾中才能忆起他们过去美好的时光来寻求一点心里的平衡. ◇4、女人永远也不知道男人为什么要在分手以后还会对她嘘寒问暖?
因为他们自己知道.他们并不是想跟你做朋友.只是想挽回这段曾经属于他的感情. ※5、女人永远也不知道男人为什么每次在听到她被欺负了会显得那么发狂?
因为他们自己知道.哪怕这次架打输了.躺下了.他也会觉得高兴.因为他们宁愿自己受到伤害.也不愿意看到你哭泣. ☆6、女人永远也不知道男人为什么在分手以后会夜夜买醉?
因为他们知道.如果今晚不麻醉自己.那么今晚只能在思念中度过. ※7. 女人永远也不知道男人为什么每次出门会出手那么大方? 因为他们知道.他们宁愿自己一个人省吃检用.也不愿意你看到你被别人看不起. ☆8.女人永远也不知道男人为什么会那么爱对她发脾气?
因为他们自己知道.对她发脾气并不是不爱她.只是希望她在以后的路上不被别人所欺骗. ☆9.女人永远也不知道男人为什么会那么在意你以前的男朋友?
因为他们自己知道.并不是他们不自信.只是他们害怕有一天你会离他而去. ※10. 女人永远也不知道男人为什么看到你为别人写的日记之后还会那么镇静的听你解释?
因为他们自己知道.自己并不是不想发火.只是希望能从你的口中得知到底是他重要还是别人重要? ☆11、女人永远也不知道男人为什么不对她说我爱你⒊个字? 因为他们知道.并不是不想说.只是他们自己明白.⒈万句我爱你用在身上也不够 2007/3/15 [转载]验证码突破学习二模拟精灵是首个公开最有效的验证码识别技术的软件, 验证码识别是一项特殊的技术,任何一个公开的验证码识别代码都会很快的失效。 在这里讨论验证码识别技术纯粹基于技术研究目的。 本文介绍的验证码识别适用于比较复杂的图片验证码,也是大多数网站采用的方法。
有一些网站的验证码极简单,例如在网页中直接显示验证码字符而不是图片,或者图片的文件名直接就是验证码上的字符。 或者有其他规律可循,或者有其他明显的漏洞可以利用(例如通过改写访问验证码页面的源代码使验证码不刷新)。 这一类的验证码识别极其简单,只要熟练掌握web库、element库的函数即可,不需要使用下面介绍的方法。 一、下载验证码样本 打开c:\test文件夹,选“查看缩略图”, img = image.new();
img2:save("c:\\test\\0001.jpg") image.del(img); 在整个验证码识别过程中,格式与后缀名一定不能搞错,否则就会失败。 另外,你可以用UltraEdit等以二进制方式打开看文件头部
首先下载: str = web.getURL("http://www.***.com/test.asp") string.save( str,"c:\\test.bin") 然后用UE打开test.bin看文件头部(第一行) jpg文件头部有 JFIF 字眼 png文件头部 有 PNG 字眼 gif文件头部有 GIF字眼 如果你搞不清楚,这时候就不要指定后缀名 二、生成验证码样本数据库 复制下面的代码并粘贴到fap程序的「脚本区块」内,然后点击"回放运行",最后再点击"读取源代码"。 local tkey ={A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0};
--在字典中添加所有数字键 for i =0,9,1 do tkey[ tostring(i) ] = 0; end; --如果一个字符有多个样本,例如 5A.jpg 5B.jpg 5C.jpg 三、验证码识别将下面的代码添加到fap模拟程序最前面的init脚本区块中即可 --从数据区块读取base64编码的图片数据
codekey = ape:loadTable("验证码样本"); local timg = {}; --这是一个图像数组,用来储存还原后的验证码样本的图片数据 --必须进行一个转换,因为codekey里面只是base64编码的普通字符串,而timg 将是真正的图片对象(二进制数据) --还原到图片对象 toImage = function(k,v) local img = image.new(); local str = string.decode( v ,"");--首先进行base64解码,将纯文本转换为二进制数据 img:setBytes( str ,"*.jpg");--将二进制数据还原为图像 timg[k] = img; end; --载入验证码样本 tkey = ape:loadTable("验证码样本"); for k,v in pairs(tkey) do --验证样本 toImage(k,v); --转换为图像 end; --转换图片验证码到字符串的函数 function ImgToString(img) function test(imgX) --test是一个被包含在函数中的内部函数 sleep(0); local limit = (60 * 20) + (60 * 20); --最小相似度 local关键字声明为局部变量 local chr = "A"; --读取的字符 --testimg是一个被包含在函数中的内部函数,作为table.foreach的回调函数,k参数表示键,v参数表示值 testimg = function(k,v) --调用image.testXX()函数得出相似度,类似的函数还有image.testX() image.test() local n = imgX:testXX(timg[k]); if(n<limit)then --比较最小相似度 limit = n; chr = k..""; end; end; --遍历timg表,并调用testimg函数 for k,v in pairs(timg) do testimg(k,v); end; return string.left(chr,1); --返回读取到的字符串首字符(如果每个字符有多个样本) end; --修剪图片 image.Crop(img, 4 ,3 , 56 ,18 ) img:bpp(1); img:bpp(24); --上面的过程必须与下载样本时的代码完全一致。 --使用split函数分割图片 local img2,img3,img4,img5 = img:split(1,4); win.messagePrint("正在检测图片,请稍候...."); return test(img2)..test(img3)..test(img4)..test(img5); end; 需要识别验证码的地方添加类似下面的代码: img = image.new()
img:getURL("http://www.***.com/test.asp","*.jpg") --因为刷新了验证码与页面不一致,把验证码画到屏幕上 local str = ImgToString(img); 上面我们用了模拟按键的方法输入验证码。 ele = wb:getEle("验证码控件名字");
ele:setAttribute("value",str)
因为我们使用img:getURL读取验证码时已经刷新了验证码。
有些验证码是绑定页面的,必须识别页面上的验证码才行。 更好的方法是使用ele:exec("Copy")函数直接拷贝页面上的图片到剪贴板。 四、关于剪切图片
五、使用种子填充算法去除验证码上的干扰线模拟精灵识别验证码的能用是强大的,一个函数即可以去除杂色杂点。 img:bpp(1)
img:bpp(24) 经过上面两句代码的处理,速度很快,所有背景、干扰点、杂色荡然无存。 下面是一个模拟精灵初步处理后的验证码图片.已经去除了杂色、杂点.但是上面还是有干扰线.
一个可选的办法是用中值滤波再处理一下。img:median(2); 一个函数调用就可以,但 下面是使用种子填充算法去除干扰线的源代码,不但能去除杂点,
下面是全部的源代码: --[[ 用一个table结构{x=0; y=0}表示图像上的「坐标点」 用一组点构成table结构表示图像上的一条「线」。所有相连的黑色的点被认为是一条「连通线」。 找出最长的一条「连通线」,被认为是字符,其他的认为是杂点。 算法原理与种子填充算法相似。 首先让用img:bpp函数处理为黑白图片,并初步去除杂色。 先找到一个黑点,创建一个表示「坐标点」对象,并添加到「连通线」中。 然后在黑点周围8个点中,再找黑色的点,找到就添加到「连通线」,这样一直递归下去 直到遍历图像所有点,可能有几块。 清除杂点使用方法 image.scan(img); 清除杂点并切去掉周围的空白 image.scan(img,true); --]] function image.scan(img,crop) --用一个table数组记录所有的「连通线」 assert(img:ok(),"image.scan 的参数必须是一个有效的图片"); local tlines ={}; --首先计算出图片的高度宽度,避免重复的调用 local w = img:width(); local h = img:height(); --[[以table形式定义一个数组,对应图象中的每个点。 作用相当一个开关,首先值为false,但黑点首次被遍历到时。把这个值变为true。 下次,再找到这个点时忽略。避免重复加入连通线。 --]] local tchked ={}; for i=0,w,1 do tchked[i]={}; for j=0,h,1 do tchked[i][j]=false; end; end; -----去噪 img:bpp(1); img:bpp(24); --首先计算出各点的颜色值,避免在循环递归中重复的取 local tcl={}; for i=0,w,1 do tcl[i]={}; for j=0,h,1 do tcl[i][j]=img:getPos(i,j); end; end; --[[ 算点数函数 参数x,y 坐标 参数tab 所属连通线; --]] local function seed(x,y,tab) ---出界了则返回 if(x<0 or y<0 or x>w or y>h) then return; end; ---点的颜色为白色时,返回,不处理。 if(tcl[x][y]==16777215) then return; end; ---值为1,则计数加1,返回 if ( tchked[x][y]) then return ; else table.insert(tab,{x=x,y=y} );--添加到连通线里 tchked[x][y]=true;---当值为0时,把值置为1。 seed(x+1,y-1,tab); seed(x,y-1,tab); seed(x-1,y-1,tab); seed(x-1,y,tab); seed(x+1,y,tab); seed(x-1,y+1,tab); seed(x,y+1,tab); return seed(x+1,y+1,tab); --这里可以用一个尾调用(参考教程中的函数部份),加快递归的速度。 end; end; --------------------------- ----遍历图像中的所有点 for i=0,w,1 do for j=0,h,1 do ---如果是黑色的点,而且没有被计过数,则调用seed函数。 if(tcl[i][j]==0 and (not tchked[i][j])) then local tab = {} seed(i,j,tab); table.insert(tlines,tab); --添加一条连通线 end; end; end; --现在tlines 里记录了的有的连通线,我们现在需要根据连通线的长度排序 sproc = function(l,l2) return table.maxn(l) > table.maxn(l2);--长的连通线排到前面 end; table.sort(tlines,sproc) --把图像全部画成白色的点 for i=0,w,1 do for j=0,h,1 do img:setPos( i , j, 16777215); end; end; --然后把最长的一条连通线画上去 for i,point in ipairs(tlines[1]) do img:setPos( point.x, point.y , 0); end; --如果需要去掉周围的空白 if(crop)then local n = table.maxn(tlines[1]) --排序最长连通线中的所有坐标点 sproc = function(pt,pt2) return (pt.x <pt2.x );--*左的排前面 end; table.sort(tlines[1],sproc); local x,x2 = tlines[1][1].x, tlines[1][n].x; --排序最长连通线中的所有坐标点 sproc = function(pt,pt2) return (pt.y <pt2.y );--*上的排前面 end; table.sort(tlines[1],sproc); local y,y2 = tlines[1][1].y, tlines[1][n].y; img:Crop( x,y,x2+1,y2) end; end; [转载]关于突破验证码的学习一
使用模拟精灵制作了大量的免费、商用群发软件,对很多复杂BT的验证码都能成功的识别。 但是验证码仍然需要精湛的技术与足够的耐心。请牢记这一点。 验证码识别不适合浮躁的人去做。 因为代码的公开后相关网站都会很快的更改验证码。 所以下面我只会介绍其原理。 公开此技术也是为了让更多的网站采取更有效的防范措施。 禁止任何人利用这里介绍的验证码识别技术滥发垃圾信息。 有一些网站的验证码极简单,例如在网页中直接显示验证码字符而不是图片,或者图片的文件名直接就是验证码上的字符。 或者有其他规律可循,或者有其他明显的漏洞可以利用(例如通过改写访问验证码页面的源代码使验证码不刷新)。 这一类的验证码识别极其简单,只要熟练掌握web库、element库的函数即可,不需要使用下面介绍的方法。 然后重复运行下面的LAScript脚本,每运行一次,就查看c:\test下自动生成的图片,把图片上的字符改为文件名. 例如图片上面显示5,就把文件名改为5.jpg. 如果变化比较复杂的验证码,可以对每个字符多用几个样本,第一个字符为验证码字符,第二个字符可以为任意字符。 例如:5a.jpg , 5b.jpg , 5c.jpg ...........等等。 样本多就会识别能力就越强。 你就可以在ApeML源代码最后面的「数据区块」中看到生成的验证码样本了。 将「数据区块」的内容复制需要使用验证码识别的fap模拟程序中覆盖「数据区块」即可。 --在字典中添加所有数字键 for i =0,9,1 do tkey[ tostring(i) ] = 0; end; --如果一个字符有多个样本,例如 5A.jpg 5B.jpg 5C.jpg codekey = ape:loadTable("验证码样本"); local timg = {}; --这是一个图像数组,用来储存还原后的验证码样本的图片数据 --必须进行一个转换,因为codekey里面只是base64编码的普通字符串,而timg 将是真正的图片对象(二进制数据) --还原到图片对象 toImage = function(k,v) local img = image.new(); local str = string.decode( v ,"");--首先进行base64解码,将纯文本转换为二进制数据 img:setBytes( str ,"*.jpg");--将二进制数据还原为图像 timg[k] = img; end; --载入验证码样本 tkey = ape:loadTable("验证码样本"); for k,v in pairs(tkey) do --验证样本 toImage(k,v); --转换为图像 end; --转换图片验证码到字符串的函数 function ImgToString(img) function test(imgX) --test是一个被包含在函数中的内部函数 sleep(0); local limit = (60 * 20) + (60 * 20); --最小相似度 local关键字声明为局部变量 local chr = "A"; --读取的字符 --testimg是一个被包含在函数中的内部函数,作为table.foreach的回调函数,k参数表示键,v参数表示值 testimg = function(k,v) --调用image.testXX()函数得出相似度,类似的函数还有image.testX() image.test() local n = imgX:testXX(timg[k]); if(n<limit)then --比较最小相似度 limit = n; chr = k..""; end; end; --遍历timg表,并调用testimg函数 for k,v in pairs(timg) do testimg(k,v); end; return string.left(chr,1); --返回读取到的字符串首字符(如果每个字符有多个样本) end; --修剪图片 image.Crop(img, 4 ,3 , 56 ,18 ) img:bpp(1); img:bpp(24); --上面的过程必须与下载样本时的代码完全一致。 --使用split函数分割图片 local img2,img3,img4,img5 = img:split(1,4); win.messagePrint("正在检测图片,请稍候...."); return test(img2)..test(img3)..test(img4)..test(img5); end; img:getURL("http://www.***.com/test.asp","*.jpg") --因为刷新了验证码与页面不一致,把验证码画到屏幕上 local str = ImgToString(img); 实际上大多时候可以用更简单的方法,如下: ele:setAttribute("value",str) 所以验证码与页面上显示的并不一样,您只需要识别最新的验证码即可。 那么可以使用image.capture函数直接抓屏屏幕上的图片即可。 请参考:image.capture函数。 然后使用 img:getClipBD() 获取图片。 请参考:ele:exec("Copy")函数 img:getClipBD()函数 img:bpp(24) 但是有时候验证码中有大量的干扰线,并且位置随机变动的太历害, 这时候我们在处理验证码以前首先去除这些干扰线并准确的去除背景提取字符. 是这样虽然去掉了干扰线,原来的字符也被少量的破坏了。 而且可以去除周围的空白(提取位置随机变化的验证码), 稍加修改还能有更多的用途. 下面是自动处理以后的效果 用一个table结构{x=0; y=0}表示图像上的「坐标点」 用一组点构成table结构表示图像上的一条「线」。所有相连的黑色的点被认为是一条「连通线」。 找出最长的一条「连通线」,被认为是字符,其他的认为是杂点。 算法原理与种子填充算法相似。 首先让用img:bpp函数处理为黑白图片,并初步去除杂色。 先找到一个黑点,创建一个表示「坐标点」对象,并添加到「连通线」中。 然后在黑点周围8个点中,再找黑色的点,找到就添加到「连通线」,这样一直递归下去 直到遍历图像所有点,可能有几块。 清除杂点使用方法 image.scan(img); 清除杂点并切去掉周围的空白 image.scan(img,true); --]] function image.scan(img,crop) --用一个table数组记录所有的「连通线」 assert(img:ok(),"image.scan 的参数必须是一个有效的图片"); local tlines ={}; --首先计算出图片的高度宽度,避免重复的调用 local w = img:width(); local h = img:height(); --[[以table形式定义一个数组,对应图象中的每个点。 作用相当一个开关,首先值为false,但黑点首次被遍历到时。把这个值变为true。 下次,再找到这个点时忽略。避免重复加入连通线。 --]] local tchked ={}; for i=0,w,1 do tchked[i]={}; for j=0,h,1 do tchked[i][j]=false; end; end; -----去噪 img:bpp(1); img:bpp(24); --首先计算出各点的颜色值,避免在循环递归中重复的取 local tcl={}; for i=0,w,1 do tcl[i]={}; for j=0,h,1 do tcl[i][j]=img:getPos(i,j); end; end; --[[ 算点数函数 参数x,y 坐标 参数tab 所属连通线; --]] local function seed(x,y,tab) ---出界了则返回 if(x<0 or y<0 or x>w or y>h) then return; end; ---点的颜色为白色时,返回,不处理。 if(tcl[x][y]==16777215) then return; end; ---值为1,则计数加1,返回 if ( tchked[x][y]) then return ; else table.insert(tab,{x=x,y=y} );--添加到连通线里 tchked[x][y]=true;---当值为0时,把值置为1。 seed(x+1,y-1,tab); seed(x,y-1,tab); seed(x-1,y-1,tab); seed(x-1,y,tab); seed(x+1,y,tab); seed(x-1,y+1,tab); seed(x,y+1,tab); return seed(x+1,y+1,tab); --这里可以用一个尾调用(参考教程中的函数部份),加快递归的速度。 end; end; --------------------------- ----遍历图像中的所有点 for i=0,w,1 do for j=0,h,1 do ---如果是黑色的点,而且没有被计过数,则调用seed函数。 if(tcl[i][j]==0 and (not tchked[i][j])) then local tab = {} seed(i,j,tab); table.insert(tlines,tab); --添加一条连通线 end; end; end; --现在tlines 里记录了的有的连通线,我们现在需要根据连通线的长度排序 sproc = function(l,l2) return table.maxn(l) > table.maxn(l2);--长的连通线排到前面 end; table.sort(tlines,sproc) --把图像全部画成白色的点 for i=0,w,1 do for j=0,h,1 do img:setPos( i , j, 16777215); end; end; --然后把最长的一条连通线画上去 for i,point in ipairs(tlines[1]) do img:setPos( point.x, point.y , 0); end; --如果需要去掉周围的空白 if(crop)then local n = table.maxn(tlines[1]) --排序最长连通线中的所有坐标点 sproc = function(pt,pt2) return (pt.x <pt2.x );--*左的排前面 end; table.sort(tlines[1],sproc); local x,x2 = tlines[1][1].x, tlines[1][n].x; --排序最长连通线中的所有坐标点 sproc = function(pt,pt2) return (pt.y <pt2.y );--*上的排前面 end; table.sort(tlines[1],sproc); local y,y2 = tlines[1][1].y, tlines[1][n].y; img:Crop( x,y,x2+1,y2) end; end; |
|
|