Почему мне это понадобилось?
Недавно, блуждаю по сайту фриланса, наткнулся на интересное задание — нужно было скачать около 65000 файлов. Скачивание ограничивалось вводом капчи, состоящей из четырех цифр. Сначала хотел использовать сервис antigate.com, о чем прямо сообщил заказчику, но мое
Немного о коде
Я программирую на PHP недолго, поэтому код у меня еще не качественный, сильно не бейте.
Пример капчи
Поехали взламывать
Для начала загружаем изображение в скрипт, определяем его высоту и ширину и устанавливаем для него белый и черный цвет.
$image = imagecreatefrompng($img);
$width = imagesx($image);
$height = imagesy($image);
$white = imagecolorallocate($image,255,255,255);
$black = imagecolorallocate($image,0,0,0);
Внимательно изучив картинку под
for ($x=0;$x<$width;$x++) {
for($y=0;$y<$height;$y++) {
$color_index = imagecolorat($image,$x,$y);
$color_back = imagecolorsforindex($image,$color_index);
if ($color_back['red'] == 216 && $color_back['green'] == 216 && $color_back['blue'] == 216) {
imagesetpixel($image,$x,$y,$white);
}
}
}
Затем перекрашиваем все цифры в черный цвет, исходя из того, что любой цвет, кроме белого, принадлежит цифрам:
for ($x=0;$x<$width;$x++) {
for($y=0;$y<$height;$y++) {
$color_index = imagecolorat($image,$x,$y);
$color_back = imagecolorsforindex($image,$color_index);
if ($color_back['red'] + $color_back['green'] + $color_back['blue'] != 765) {
imagesetpixel($image,$x,$y,$black);
}
}
}
Далее снова взялся за
11111111
00000011
00000011
00000110
00001100
00011000
00110000
01100000
11000000
11000000
Где 0 — это белый пиксель, а 1 — черный. Чтобы было меньше кода для сравнивания цифр, я преобразовал матрицы цифр в строку. Все та же семерка:
11111111000000110000001100000110000011000001100000110000011000001100000011000000
Далее анализируем нужный нам квадрат с цифрой, указывая, что белый пиксель равен нулю, а черный — единице. Для первой цифры:
for ($x=15;$x<=22;$x++) {
for($y=0;$y<$height;$y++) {
$color_index = imagecolorat($image,$x,$y);
$color_back = imagecolorsforindex($image,$color_index);
if ($color_back['red'] + $color_back['green'] + $color_back['blue'] == 0) {
$temp[$y][] = 1;
} else {
$temp[$y][] = 0;
}
}
}
Для второй — четвертой цифр аналогично.
Получается двухмерный массив, превращаем его в одномерный:
for ($i=0;$i<count($temp);$i++) {
$temp[$i] = implode('',$temp[$i]);
}
Далее из получившегося массива удаляем чистые ряды, то есть ряды, содержащие только '00000000'
foreach ($temp as $value) {
if ($value != '00000000') {
$digit1[] = $value;
}
}
Получившийся массив $digit1 объединяем в строку:
$digit1 = implode('',$digit1);
.И сравниваем получившееся значение с имеющимися матрицами цифр с помощью небольшой самописной функции:
function compare($digit) {
$one = file_get_contents('1.txt');
$two = file_get_contents('2.txt');
$three = file_get_contents('3.txt');
$four = file_get_contents('4.txt');
$five = file_get_contents('5.txt');
$six = file_get_contents('6.txt');
$seven = file_get_contents('7.txt');
$eight = file_get_contents('8.txt');
$nine = file_get_contents('9.txt');
$zero = file_get_contents('0.txt');
if ($digit === $one) $value = '1';
if ($digit === $two) $value = '2';
if ($digit === $three) $value = '3';
if ($digit === $four) $value = '4';
if ($digit === $five) $value = '5';
if ($digit === $six) $value = '6';
if ($digit === $seven) $value = '7';
if ($digit === $eight) $value = '8';
if ($digit === $nine) $value = '9';
if ($digit === $zero) $value = '0';
return $value;
}
Результат сразу для четырех цифр:
$result = compare($digit1) . compare($digit2) . compare($digit3) . compare($digit4);
return $result;
Результаты
- Написано всего 150 строк кода за 3 часа.
- Приобретен опыт взлома капчи.
- Получен огромный выигрыш во времени (antigate разгадывает капчу за 10-20 секунд, скрипт за 1-2).
- Сэкономлено почти $100.