source: pwntcha/trunk/src/scode.c @ 400

Last change on this file since 400 was 400, checked in by Sam Hocevar, 15 years ago
  • scode captcha decoder
  • Property svn:keywords set to Id
File size: 3.2 KB
Line 
1/*
2 * scode.c: decode scode captchas
3 * $Id: scode.c 400 2005-01-04 02:12:26Z sam $
4 *
5 * Copyright: (c) 2004 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
16#include "config.h"
17#include "common.h"
18
19static char find_glyph(struct image *img, int xmin, int xmax);
20
21/* Main function */
22char *decode_scode(struct image *img)
23{
24    char *result;
25    int stats[256];
26    int x, y, i, incell = 0, cur = 0, xmin = 0;
27    int r, g, b;
28    struct image *tmp1;
29
30    /* allocate enough place */
31    result = malloc(1024 * sizeof(char));
32
33    /* Detect background: first 3 lines */
34    for(i = 0; i < 256; i++)
35        stats[i] = 0;
36
37    for(y = 0; y < 3; y++)
38        for(x = 0; x < img->width; x++)
39        {
40            getpixel(img, x, y, &r, &g, &b);
41            stats[r]++;
42        }
43
44    /* Set non-background colours to 0 */
45    tmp1 = image_new(img->width, img->height);
46
47    for(y = 0; y < img->height; y++)
48        for(x = 0; x < img->width; x++)
49        {
50            getpixel(img, x, y, &r, &g, &b);
51            if(stats[r])
52                setpixel(tmp1, x, y, 255, 255, 255);
53            else
54                setpixel(tmp1, x, y, 0, 0, 0);
55        }
56
57    /* Decode glyphs */
58    for(x = 0; x < img->width; x++)
59    {
60        int found = 0;
61        for(y = 0; y < img->height; y++)
62        {
63            getpixel(tmp1, x, y, &r, &g, &b);
64            if(!r)
65            {
66                found = 1;
67                break;
68            }
69        }
70        if(found && !incell)
71        {
72            incell = 1;
73            xmin = x;
74        }
75        else if(!found && incell)
76        {
77            incell = 0;
78            /* Find glyph */
79            result[cur++] = find_glyph(tmp1, xmin, x);
80        }
81    }
82
83    image_free(tmp1);
84
85    result[cur] = 0;
86    return result;
87}
88
89static char find_glyph(struct image *img, int xmin, int xmax)
90{
91    int ymin = -1, ymax = -1;
92    int x, y, count = 0;
93    int r, g, b;
94
95    /* Compute vertical bounds of glyph */
96    for(y = 0; y < img->height; y++)
97    {
98        int found = 0;
99        for(x = xmin; x < xmax; x++)
100        {
101            getpixel(img, x, y, &r, &g, &b);
102            if(!r)
103            {
104                found = 1;
105                break;
106            }
107        }
108        if(found)
109        {
110            if(ymin == -1)
111                ymin = y;
112            else
113                ymax = y + 1;
114        }
115    }
116
117    for(x = xmin; x < xmax; x++)
118    {
119        for(y = ymin; y < ymax; y++)
120        {
121            getpixel(img, x, y, &r, &g, &b);
122            if(!r)
123                count += y - ymin;
124        }
125    }
126
127    switch(count)
128    {
129        case 162: return '0';
130        case 131: return '1';
131        case 150: return '2';
132        case 139: return '3';
133        case 155: return '4';
134        case 159: return '5';
135        case 181: return '6';
136        case  90: return '7';
137        case 180: return '8';
138        case 170: return '9';
139        default:
140            dprintf("don't know about checksum %i\n", count);
141            return '?';
142    }
143}
144
Note: See TracBrowser for help on using the repository browser.