Created
November 6, 2012 04:23
-
-
Save rdgt321/4022538 to your computer and use it in GitHub Desktop.
Simple recognition of 4-bit cpatcha of NJU bras
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.Color; | |
import java.awt.Graphics; | |
import java.awt.Image; | |
import java.awt.image.ImageObserver; | |
import java.awt.image.PixelGrabber; | |
import java.io.IOException; | |
import java.net.*; | |
import javax.imageio.ImageIO; | |
import javax.swing.JFrame; | |
//仅针对PNJU的简单验证码,测试通过率95%以上 | |
public class captcha extends JFrame { | |
private static final String URL = "http://p.nju.edu.cn/portal/img.html"; | |
Image img = null; | |
int num1, num2, num3, num4;// 有效灰度像素数 | |
int cnum1, cnum2, cnum3, cnum4;// 画Y轴线与数字交叉次数 | |
int lnum1, lnum2, lnum3, lnum4;// 画Y轴线与数字重叠点数 判断2、3 | |
Color color; | |
public captcha() { | |
setVisible(true); | |
setSize(200, 200); | |
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
new Thread(new Runnable() { | |
public void run() { | |
while (true) { | |
try { | |
Thread.sleep(200); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
repaint(); | |
} | |
} | |
}).start(); | |
; | |
} | |
@Override | |
public void paint(Graphics g) { | |
g.drawImage(img, 0, 40, 160, 70, this); | |
g.setColor(Color.black); | |
// 分割区域线 | |
g.drawLine((int) (10 * 2), 0, (int) (10 * 2), 200); | |
g.drawLine((int) (26 * 2), 0, (int) (26 * 2), 200); | |
g.drawLine((int) (42 * 2), 0, (int) (42 * 2), 200); | |
g.drawLine((int) (59 * 2), 0, (int) (59 * 2), 200); | |
g.drawLine((int) (75 * 2), 0, (int) (75 * 2), 200); | |
} | |
public Image load() { | |
img = null; | |
try { | |
URL url = new URL(URL); | |
img = ImageIO.read(url); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return img; | |
} | |
public void analyze(Image image) { | |
int err = 0; | |
int x = 0; | |
int width = image.getWidth(null); | |
int height = image.getHeight(null); | |
int pixels[] = new int[width * height]; | |
PixelGrabber pg = new PixelGrabber(image, 0, 0, width, height, pixels, | |
0, width); | |
try { | |
pg.grabPixels(); | |
} catch (InterruptedException e) { | |
System.err.println("interrupted waiting for pixels!"); | |
e.printStackTrace(); | |
} | |
if ((pg.getStatus() & ImageObserver.ABORT) != 0) { | |
System.err.println("image fetch aborted or errored"); | |
} | |
// y | |
for (int i = 0; i < height; i++) { | |
// x | |
for (int j = 0; j < width; j++) { | |
int n = i * width + j; | |
if ((j >= 0 && j <= 10) || (j <= 79 && j >= 76)) { | |
continue;//非数字区域 跳过 | |
} | |
if (getP(pixels[n]) != 442) {//有效像素点的总RGB灰度为442 蓝色 | |
continue; | |
} | |
if (j >= 10 && j <= 25) {// 第一个数字 | |
num1++; | |
} else if (j >= 26 && j <= 42) {// 第二个数字 | |
num2++; | |
} else if (j >= 43 && j <= 59) {// 第三个数字 | |
num3++; | |
} else if (j >= 60 && j <= 75) {// 第四个数字 | |
num4++; | |
} else { | |
err++; | |
} | |
} | |
} | |
cnum1 = getCrossTime(17, height, width, pixels);// 数字一与x=17交错次数 | |
lnum1 = getTime(21, height, width, pixels);//与x=21像素点重叠次数 | |
cnum2 = getCrossTime(33, height, width, pixels);// 数字二与x=33交错次数 | |
lnum2 = getTime(37, height, width, pixels); | |
cnum3 = getCrossTime(50, height, width, pixels);// 数字三与x=50交错次数 | |
lnum3 = getTime(54, height, width, pixels); | |
cnum4 = getCrossTime(67, height, width, pixels);// 数字四与x=67交错次数 | |
lnum4 = getTime(71, height, width, pixels); | |
System.out.println("num1:" + num1); | |
System.out.println("cnum1:" + cnum1); | |
System.out.println("num2:" + num2); | |
System.out.println("cnum2:" + cnum2); | |
System.out.println("num3:" + num3); | |
System.out.println("cnum3:" + cnum3); | |
System.out.println("num4:" + num4); | |
System.out.println("cnum4:" + cnum4); | |
System.out.println("lnum1:" + lnum1); | |
System.out.println("lnum2:" + lnum2); | |
System.out.println("lnum3:" + lnum3); | |
System.out.println("lnum4:" + lnum4); | |
System.out.println("err:" + err); | |
System.out.println("result:" + getInt(num1, cnum1, lnum1) | |
+ getInt(num2, cnum2, lnum2) + getInt(num3, cnum3, lnum3) | |
+ getInt(num4, cnum4, lnum4)); | |
} | |
public int getCrossTime(int x, int height, int width, int[] pixels) { | |
boolean in = false; | |
int time = 0; | |
int n = 0; | |
for (int i = 0; i < height; i++) { | |
n = i * width + x; | |
if (getP(pixels[n]) == 442) { | |
if (!in) { | |
in = true; | |
time++; | |
} | |
} else { | |
if (in) { | |
in = false; | |
} | |
} | |
} | |
return time; | |
} | |
public int getTime(int x, int height, int width, int[] pixels) { | |
int time = 0; | |
int n = 0; | |
for (int i = 0; i < height; i++) { | |
n = i * width + x; | |
if (getP(pixels[n]) == 442) { | |
time++; | |
} | |
} | |
return time >= 12 ? 3 : 2; | |
} | |
public int getInt(int num, int cnum, int lnum) { | |
switch (num) { | |
case 81: | |
return 1; | |
case 96: | |
case 100: | |
return 2; | |
case 97: | |
return 3; | |
case 111: | |
case 101: | |
return 4; | |
case 105: | |
case 114: | |
case 95: | |
return 5; | |
case 122: | |
case 116: | |
return 6; | |
case 76: | |
case 72: | |
case 82: | |
return 7; | |
case 123: | |
case 128: | |
case 129: | |
return 8; | |
case 117: | |
case 119: | |
return 9; | |
case 125: | |
case 112: | |
return 0; | |
// 下面是几个出现映射重叠的数字 用Y-cross-time和Y-time进行二次判别 | |
case 92: | |
case 98: | |
switch (cnum) { | |
case 1: | |
return 1; | |
case 3: | |
switch (lnum) { | |
case 2: | |
return 2; | |
case 3: | |
return 3; | |
default: | |
return -1; | |
} | |
default: | |
return -1; | |
} | |
case 120: | |
switch (cnum) { | |
case 2: | |
return 0; | |
case 3: | |
return 6; | |
default: | |
return -1; | |
} | |
case 107: | |
switch (cnum) { | |
case 2: | |
return 4; | |
case 3: | |
return 9; | |
default: | |
return -1; | |
} | |
default: | |
return -1; | |
} | |
} | |
// 得到像素点rgb总值 | |
public int getP(int c) { | |
return getR(c) + getG(c) + getB(c); | |
} | |
public int getR(int c) { | |
return c >> 16 & 0xFF; | |
} | |
public int getG(int c) { | |
return c >> 8 & 0xFF; | |
} | |
public int getB(int c) { | |
return c & 0xFF; | |
} | |
public static void main(String[] args) { | |
captcha captcha = new captcha(); | |
captcha.analyze(captcha.load()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment