source: pwntcha/trunk/src/linuxfr.c @ 419

Last change on this file since 419 was 419, checked in by Sam Hocevar, 16 years ago
  • linuxfr.org captchas
  • Property svn:keywords set to Id
File size: 4.0 KB
Line 
1/*
2 * linuxfr.c: decode linuxfr.org captchas
3 * $Id: linuxfr.c 419 2005-01-04 23:10:43Z sam $
4 *
5 * Copyright: (c) 2005 Sam Hocevar <sam@zoy.org>
6 *   This program is free software; you can redistribute it and/or
7 *   modify it under the terms of the Do What The Fuck You Want To
8 *   Public License as published by Banlu Kemiyatorn. See
9 *   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <limits.h>
16
17#include "config.h"
18#include "common.h"
19
20#define FONTNAME "share/font_linuxfr.png"
21
22/* Main function */
23char *decode_linuxfr(struct image *img)
24{
25    char all[] = "abcdefghijklmnopqrstuvwxyz"
26                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
27                 "0123456789";
28    char *result;
29    struct image *tmp, *font;
30    int x, y, r, g, b, i, j, c;
31    int stats[40];
32
33    font = image_load(FONTNAME);
34    if(!font)
35    {
36        fprintf(stderr, "cannot load font %s\n", FONTNAME);
37        exit(-1);
38    }
39
40    /* linuxfr captchas have 7 characters */
41    result = malloc(8 * sizeof(char));
42    memset(result, '\0', 8);
43
44    tmp = filter_equalize(img, 150);
45
46    for(y = 0; y < img->height; y++)
47    {
48        int count = 0;
49        for(x = 0; x < img->width; x++)
50        {
51            getpixel(tmp, x, y, &r, &g, &b);
52            if(r == 0)
53                count++;
54        }
55        stats[y] = count;
56    }
57
58    /* Find 7 consecutive lines that have at least 14 pixels; they're
59     * baseline candidates */
60    for(y = 0; y < img->height - 11; y++)
61    {
62        int ycan = 1;
63        for(j = 3; j < 10; j++)
64        {
65            if(stats[y + j] < 14)
66            {
67                ycan = 0;
68                y = y + j - 3;
69                break;
70            }
71        }
72        if(!ycan)
73            continue;
74
75        /* Find 7 consecutive cells that have at least 2 pixels on
76         * each line; they're base column candidates */
77        for(x = 0; x < img->width - 9 * 7 + 1; x++)
78        {
79            int xcan = 1;
80            for(c = 0; c < 7; c++, xcan)
81            {
82                for(j = 3; j < 10; j++)
83                {
84                    int count = 0;
85                    for(i = 0; i < 8; i++)
86                    {
87                        getpixel(tmp, x + c * 9 + i, y + j, &r, &g, &b);
88                        if(r == 0)
89                        {
90                            count++;
91                            if(count == 2)
92                                break;
93                        }
94                    }
95                    if(count < 2)
96                    {
97                        xcan = 0;
98                        break;
99                    }
100                }
101            }
102            if(!xcan)
103                continue;
104
105            /* Now we have an (x,y) candidate - try to fit 7 characters */
106            for(c = 0; c < 7; c++, xcan)
107            {
108                int r2, g2, b2, test, tcan;
109                for(test = 0; test < 62; test++)
110                {
111                    tcan = 1;
112                    for(j = 0; j < 12; j++, tcan)
113                        for(i = 0; i < 8; i++)
114                        {
115                            getpixel(tmp, x + c * 9 + i, y + j, &r, &g, &b);
116                            getpixel(font, test * 9 + i, j, &r2, &g2, &b2);
117                            /* Only die if font is black and image is white */
118                            if(r > r2)
119                            {
120                                tcan = 0;
121                                break;
122                            }
123                        }
124                    if(tcan)
125                    {
126                        result[c] = all[test];
127                        result[c+1] = '\0';
128                        break;
129                    }
130                }
131                if(!tcan)
132                {
133                    xcan = 0;
134                    break;
135                }
136            }
137            if(xcan)
138            {
139                break;
140            }
141        }
142    }
143
144    image_free(tmp);
145    image_free(font);
146
147    if(strlen(result) != 7)
148    {
149        free(result);
150        return NULL;
151    }
152
153    return result;
154}
155
Note: See TracBrowser for help on using the repository browser.