събота, 29 март 2008 г.

Java Captcha

Стана ми интересно какви captcha-s има по света и колко са сигурни:)
Ето няколко примера:

1. *Лесни (и средно лесни) за декодиране








2. Трудни за декодиране








3. Още по трудни :)


- Чичо Гугъл (Google)




- Yahoo




- Hotmail



- ICQ





Като поогледах някои captchas стигнах до следните изводи (има няколко статии в които има по обстойно изброяване на необходимите условия един captcha да е добър, една от тях е дадена като линк по долу):
- хубаво е да не съдържат думи или поне от богат речник (например Facebook предлагат комбинация от 4 символа + дума или дума + 4 символа)
- фона да не контрастира много в смисъл да не са много отчетливи символите.
- самите символи да не са подредени на една линия и ако е възможно да са изкривени и завъртяни с някоя афинна трансформация по "случаен" принцип
- около и до самите символи да се доляпят всякакви елементи (точки, криви, фигурки, които да изкривяват самия символ)
- да се използват различни шрифтове за символите

От последната картинка с captcha na ICQ ми дойде на ум за фон да се използва някаква случайна плазма и така попаднах на един аплет за случайна фрактална плазма http://www.ic.sunysb.edu/Stu/jseyster/plasma/index.html
Кода който предлага Justin Seyster на http://www.ic.sunysb.edu/Stu/jseyster/plasma/source.html съм модифицирал минимално колкото да ми тръгне като Swing за експеимента. Оказа се че и това не е толкова лесно защото има един лек бъг в java.awt.Component.createImage(int width, int height) за приложения различни от аплет при стандартното извикване на метода с цел създаване на Image, метода връща null. За мое щастие след час два намерих решението - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4066665
И всичко тръгна:)
Ето го крайния резултат:























package captcha;

/* Plasma.java *
* Written by Justin Seyster and released into public domain. *
* Generates a "plasma fractal" using random midpoint displacement. */

import java.applet.Applet;
import java.awt.*;
import java.awt.image.MemoryImageSource;

import javax.swing.JComponent;

public class Plasma extends JComponent//Applet
{

Image Buffer; //A buffer used to store the image
Graphics Context; //Used to draw to the buffer.

//Randomly displaces color value for midpoint depending on size
//of grid piece.
float Displace(float num)
{
float max = num / (float)(getSize().width + getSize().height) * 3;
return ((float)Math.random() - 0.5f) * max;
}

//Returns a color based on a color value, c.
Color ComputeColor(float c)
{
float Red = 0;
float Green = 0;
float Blue = 0;

if (c < red =" c" red =" (1.0f">= 0.3f && c < green =" (c" green =" (0.3f" green =" (1.3f">= 0.5f)
{
Blue = (c - 0.5f) * 2;
}
else
{
Blue = (0.5f - c) * 2;
}

return new Color(Red, Green, Blue);
}

//This is something of a "helper function" to create an initial grid
//before the recursive function is called.
void drawPlasma(Graphics g, int width, int height)
{
float c1, c2, c3, c4;

//Assign the four corners of the intial grid random color values
//These will end up being the colors of the four corners of the applet.
c1 = (float)Math.random();
c2 = (float)Math.random();
c3 = (float)Math.random();
c4 = (float)Math.random();

DivideGrid(g, 0, 0, width , height , c1, c2, c3, c4);
}

//This is the recursive function that implements the random midpoint
//displacement algorithm. It will call itself until the grid pieces
//become smaller than one pixel.
void DivideGrid(Graphics g, float x, float y, float width, float height, float c1, float c2, float c3, float c4)
{
float Edge1, Edge2, Edge3, Edge4, Middle;
float newWidth = width / 2;
float newHeight = height / 2;

if (width > 2 || height > 2)
{
Middle = (c1 + c2 + c3 + c4) / 4 + Displace(newWidth + newHeight); //Randomly displace the midpoint!
Edge1 = (c1 + c2) / 2; //Calculate the edges by averaging the two corners of each edge.
Edge2 = (c2 + c3) / 2;
Edge3 = (c3 + c4) / 2;
Edge4 = (c4 + c1) / 2;

//Make sure that the midpoint doesn't accidentally "randomly displaced" past the boundaries!
if (Middle < middle =" 0;"> 1.0f)
{
Middle = 1.0f;
}

//Do the operation over again for each of the four new grids.
DivideGrid(g, x, y, newWidth, newHeight, c1, Edge1, Middle, Edge4);
DivideGrid(g, x + newWidth, y, newWidth, newHeight, Edge1, c2, Edge2, Middle);
DivideGrid(g, x + newWidth, y + newHeight, newWidth, newHeight, Middle, Edge2, c3, Edge3);
DivideGrid(g, x, y + newHeight, newWidth, newHeight, Edge4, Middle, Edge3, c4);
}
else //This is the "base case," where each grid piece is less than the size of a pixel.
{
//The four corners of the grid piece will be averaged and drawn as a single pixel.
float c = (c1 + c2 + c3 + c4) / 4;

g.setColor(ComputeColor(c));
g.drawRect((int)x, (int)y, 1, 1); //Java doesn't have a function to draw a single pixel, so
//a 1 by 1 rectangle is used.
}
}

//Draw a new plasma fractal whenever the applet is clicked.
public boolean mouseUp(Event evt, int x, int y)
{
drawPlasma(Context, getSize().width, getSize().height);
repaint(); //Force the applet to draw the new plasma fractal.

return false;
}

//Whenever something temporarily obscures the applet, it must be redrawn manually.
//Since the fractal is stored in an offscreen buffer, this function only needs to
//draw the buffer to the screen again.
// public void paint(Graphics g)
// {
// g.drawImage(Buffer, 0, 0, this);
// //g.drawString("Hellooow World",20,40);
// }



public void paint(Graphics g)
{
update(g);
}

public void update(Graphics g) {

if( Buffer == null ) {

Buffer = createImage(1000,1000); //(100,100);

Context = Buffer.getGraphics();
drawPlasma(Context, getSize().width, getSize().height);
}

g.drawImage(Buffer, 0, 0, this);
}



public String getAppletInfo()
{
return "Plasma Fractal. Written January, 2002 by Justin Seyster.";
}

public void init()
{
this.setVisible(true);
// Buffer = createImage(10, 10); //Set up the graphics buffer and context.
// Context = Buffer.getGraphics();
// drawPlasma(Context, getSize().width, getSize().height); //Draw the first plasma fractal.
}
};

package captcha;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class Main {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Plasma p = new Plasma();
p.setVisible(true);
p.init();

JFrame f = new JFrame("Plasma Effect");
f.getContentPane().add(p);

f.setSize(1000, 1000);
f.setLocation(100, 100);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setVisible(true);
}
}


Амин:)


Връзки / Links:
http://www.ic.sunysb.edu/Stu/jseyster/plasma/index.html
http://www.ic.sunysb.edu/Stu/jseyster/plasma/source.html

Безценното лекарство: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4066665
http://sam.zoy.org/pwntcha/
http://www.andrewtimberlake.com/blog/2006/06/developing-a-captcha-implementation-in-java.html
http://www.lafdc.com/captcha/


* Тук категоризацията - Лесни, Трудни, Още по трудни е относителна.

събота, 15 март 2008 г.

profile + export java

edit /etc/profile

export JAVA_HOME=/usr/local/jdk1.6.0_05/bin/java
export PATH=/usr/local/jdk1.6.0_05:$PATH

вторник, 19 февруари 2008 г.

Показване на кирилица на Wine / How to get cyrillic fonts to show up in Wine

По подразбиране UTF-8 би трябщало да върши чудесна работа, все пак някои приложения използват 1251 и затова се налага да изпълним следните 2 стъпки:

sudo locale-gen ru_RU.CP1251
(1-генериране на кирилски локал)

/home/stanley/.wine/drive_c/Program Files/QIP# LANG=ru_RU.CP1251 wine qip&
(2- извикване на някое приложение)

Аналогично може да се постъпи и с
ru_RU.UTF-8

Източник / Source: http://ubuntuforums.org/archive/index.php/t-277477.html

вторник, 22 януари 2008 г.



Търся в Гуугъл: XMLEncoder -> http://www.java2s.com/Code/Java/Swing-JFC/TheMyBeanJavaBeanComponent.htm

The MyBean JavaBean Component


import java.awt.Point;import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;import java.io.FileOutputStream;
import java.io.IOException;
public class MyBean
{
private String names[];
private Point p;
private int length;
public String[] getNames() { return names; }
public Point getPoint() { return p; }
public int getLength() { return length; }
public void setNames(String newValue[]) { names = newValue; }
public void setPoint(Point newValue) { p = newValue; }
public void setLength(int newValue) { length = newValue; }
public static void main(String args[]) throws IOException
{
// Create MyBean
MyBean saveme = new MyBean();
saveme.setNames(new String[] { "one", "two", "three" });
saveme.setPoint(new Point(15, 27));
saveme.setLength(6);
// Save
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream( new FileOutputStream("C:\\saveme.xml")));
encoder.writeObject(saveme); encoder.close();
}
}

понеделник, 21 януари 2008 г.

Application properties



Записване на настройки на приложение перманентно:

- properties file

- java.beans.XMLEncoder
java.beans.XMLEncoder and java.beans.XMLDecoder. Will serialize a vector straight off without you having to write any code IF theobjects in the vector have:1. A default public constructor2. public accessor methods for the object properties you want toserialize OR the properties are publicNo need to parse anything or load up an XML parser. It works much likeObjectInputStream and ObjectOutputStream, except what you get is XML.

- java.io.Serializable
- JAXB
- Java Persistence API