#include #include #include #include #include #include /* This code is only a C implementation (with some minor modifications) of this captcha generator : http://logz.org/captchaz/ Copyright November 2012 Grégory Soutadé Copyright July 2007 Loz LICENCE : Copyleft, Licence Art Libre (http://artlibre.org/licence/lal) Modifications : * Group letters * Add another layer for letter rendering (more confusing) * Change start, not appropriate for big fonts * Change min/max font size You need libgd2-xpm-dev package It's recommanded the included font "scrawl.ttf" */ #define MAX(a, b) (((a) >= (b)) ? (a) : (b)) // If not defined /* int overflow2(int a, int b) */ /* { */ /* if(a < 0 || b < 0) { */ /* fprintf(stderr, "gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n"); */ /* return 1; */ /* } */ /* if(b == 0) */ /* return 0; */ /* if(a > 0xFFFFFFFF / b) { */ /* fprintf(stderr, "gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); */ /* return 1; */ /* } */ /* return 0; */ /* } */ static int my_rand(int min, int max) { int val; struct timeval tv; static unsigned int seed = 0; int interval; if (seed == 0) { gettimeofday(&tv, NULL); seed = tv.tv_usec; } val = rand_r(&seed); if (min < 0) { if (max < 0) interval = -(min-max); else interval = max-min; } else interval = max-min; val = (int)(((double)val/(double)RAND_MAX)*(double)(interval)); val += min; /* printf("rand [%d..%d] %d\n", min, max, val); */ return val; } static inline int random_color(gdImagePtr im, int a, int b) { return gdImageColorAllocate(im, my_rand(a,b), my_rand(a,b), my_rand(a,b)); } static int generate_captcha(int width, int height, int inverse, char* font, char* phrase, char* out) { gdImagePtr im; int R, c1, c2; int wd, x, y, w1, w2, limit, n, p, r, g, b; int size, half, len; double rotation; char letter[2] = {0, 0}; int brect[8]; char* error; const double rad = 3.14/(double)180; // initialize in-memory image with gd library im = gdImageCreateTrueColor(width, height); R = (inverse) ? 0xFF : 0x00; gdImageFilledRectangle(im, 0, 0, width, height, random_color(im, 222^R, 255^R)); c1 = my_rand(150^R, 185^R); c2 = my_rand(195^R, 230^R); // encolour bg wd=20; x=0; while (x < width) { gdImageFilledRectangle(im, x, 0, x+wd, height, random_color(im, 222^R, 255^R)); x += wd; wd += MAX(10, my_rand(0, 20) - 10); } // make interesting background I, lines wd=4; w1=0; w2=0; for(x=0; x height) && (x > height)) // ??? break; } // more disturbing II, random letters limit = my_rand(30, 90); for(n=0; n