
Captcha in webpages is designed to avoid bots, I used captcha in my desktop application to avoid accidental processing on high critical transaction as you can see at my screenshot above.
First I initialized array of alphanumeric, I don't use some of them like '1', 'i', '5', 's' to avoid misreading.
private String[] token = new String[]{"3", "r", "c", "t", "9",
"n", "x", "a", "j", "8",
"d", "p", "f", "y", "7",
"h", "k"};
This array will be shuffled everytime the class created using Collections.shuffle() method.java.util.List l = Arrays.asList(token);
Collections.shuffle(l);
Then simply read the shuffled array into a String variable.captcha = token[0] + token[1] + token[2] + token[3];
The next thing to do is paint the component. Step one is drawing the horizontal and vertical gridlines with random color.Graphics2D g2d = (Graphics2D) g.create();
Random r = new Random();
for (int x = 10; x < getWidth(); x+=10) {
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawLine(x, 0, x, getHeight());
}
for (int y = 10; y < getHeight(); y+=10) {
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawLine(0, y, getWidth(), y);
}
Step two is drawing text shadow. This step is optional.g2d.setColor(Color.BLACK);
fm = getFontMetrics(bigFont);
g2d.drawString(token[0], 7, fm.getHeight() + 2);
g2d.drawString(token[1], 7 + fm.getWidths()[0], fm.getHeight() + 2);
g2d.drawString(token[2], 7 + (fm.getWidths()[0]*2), fm.getHeight() + 2);
g2d.drawString(token[3], 7 + (fm.getWidths()[0]*3), fm.getHeight() + 2);
Step three is drawing the text itself, each letter is drawn using random color too.g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawString(token[0], 5, fm.getHeight());
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawString(token[1], 5 + fm.getWidths()[0], fm.getHeight());
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawString(token[2], 5 + (fm.getWidths()[0]*2), fm.getHeight());
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawString(token[3], 5 + (fm.getWidths()[0]*3), fm.getHeight());
After painting is done, the last thing should be done is create comparing method.public boolean match(String input) {
return (input.equalsIgnoreCase(captcha));
}
From your application, just create a new instance of the class, waiting for user input then compare them.wCaptcha c = new wCaptcha();
. . .
. . .
. . .
c.match(txtInput.getText());
The complete source is below.import java.util.*;
import java.awt.*;
import javax.swing.*;
public class wCaptcha extends JPanel {
private String[] token = new String[]{"3", "r", "c", "t", "9",
"n", "x", "a", "j", "8",
"d", "p", "f", "y", "7",
"h", "k"};
private String captcha = new String();
private Font bigFont;
private FontMetrics fm;
public wCaptcha() {
super();
initData();
initUI();
}
private void initData() {
java.util.List l = Arrays.asList(token);
Collections.shuffle(l);
captcha = token[0] + token[1] + token[2] + token[3];
}
private void initUI() {
setDoubleBuffered(true);
bigFont = new Font("Monospaced",Font.BOLD,getSize2D() + 20);
fm = getFontMetrics(bigFont);
setBorder(null);
setPreferredSize(new Dimension((fm.getWidths()[0]*4) + 27,
fm.getHeight() + fm.getMaxDescent() + 2));
setMaximumSize(new Dimension((fm.getWidths()[0]*4) + 27,
fm.getHeight() + fm.getMaxDescent() + 2));
setMinimumSize(new Dimension((fm.getWidths()[0]*4) + 27,
fm.getHeight() + fm.getMaxDescent() + 2));
setBackground(Color.WHITE);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Random r = new Random();
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setFont(bigFont);
g2d.translate(0, 0);
for (int x = 10; x < getWidth(); x+=10) {
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawLine(x, 0, x, getHeight());
}
for (int y = 10; y < getHeight(); y+=10) {
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawLine(0, y, getWidth(), y);
}
g2d.setColor(Color.BLACK);
g2d.drawString(token[0], 7, fm.getHeight() + 2);
g2d.drawString(token[1], 7 + fm.getWidths()[0], fm.getHeight() + 2);
g2d.drawString(token[2], 7 + (fm.getWidths()[0]*2), fm.getHeight() + 2);
g2d.drawString(token[3], 7 + (fm.getWidths()[0]*3), fm.getHeight() + 2);
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawString(token[0], 5, fm.getHeight());
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawString(token[1], 5 + fm.getWidths()[0], fm.getHeight());
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawString(token[2], 5 + (fm.getWidths()[0]*2), fm.getHeight());
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawString(token[3], 5 + (fm.getWidths()[0]*3), fm.getHeight());
}
public boolean match(String input) {
return (input.equalsIgnoreCase(captcha));
}
}
Monday, April 07, 2008
Create Your Own Simple, Fully Customized Captcha in Desktop Java
Subscribe to:
Post Comments (Atom)





3 comments:
The site in general is nice and useful, thanks. I commented on this post because the captcha caught my attention.
Wow i needed captcha code so thanks for sharing i will use it for my blog. I will check it out if any problems i will conatct you.
Good website
Im having a little bit to trouble with builing a field which displays the text, can anyone help please?
Post a Comment