Skip to content

Instantly share code, notes, and snippets.

@rdgt321
Created November 6, 2012 04:23
Show Gist options
  • Save rdgt321/4022538 to your computer and use it in GitHub Desktop.
Save rdgt321/4022538 to your computer and use it in GitHub Desktop.
Simple recognition of 4-bit cpatcha of NJU bras
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