В прошлый раз мы остановились на таблице соответствия “код в URL картинки –> пяти-значный код Captcha”. В общем виде таблица выглядела следующим образом:
7 9 5 0
1101112 1110012 1101012 1100002
8 6 7 5
1110002 1101102 1101012 1101012
2 4 5 6
1100102 1101002 1101012 1101102
Процедура, определяющая код Captcha была построена вот так:
function Captcha(URL: string):string;
var aURL: TURLComponents;
ParamStr: string; //строка, содержащая код каптчи
code: string; //7-ми значнй код из каптчи
i,j:integer;
begin
//разбиваем УРЛ на составляющие
Result:=URL;
fillchar(aurl, sizeof(turlcomponents), 0);
with aurl do
begin
lpszscheme := nil;
dwschemelength := internet_max_scheme_length;
lpszhostname := nil;
dwhostnamelength := internet_max_host_name_length;
lpszusername := nil;
dwusernamelength := internet_max_user_name_length;
lpszpassword := nil;
dwpasswordlength := internet_max_password_length;
lpszurlpath := nil;
dwurlpathlength := internet_max_path_length;
lpszextrainfo := nil;
dwextrainfolength := internet_max_path_length;
dwstructsize := sizeof(aurl);
end;
if internetcrackurl(pchar(Result), length(Result), 0, aurl) then
begin
ParamStr:=copy(aurl.lpszExtraInfo,5, length(aurl.lpszExtraInfo)-4);
//выдираем 7-ми значный код и подбираем ему число
Result:='';
for I:=1 to 5 do //всего 35 цифр по 7 цифр на знак
begin
code:=copy(ParamStr,i+7*(i-1)-(i-1),7);
for j := 0 to High(MCat_Captcha) do
if code=Cat_Captcha[j] then
Result:=Result+IntToStr(j);
end;
end;
ShowMessage('Код Captcha '+Result)
end;
И первое, что хочется сказать по поводу этой процедуры – она просто так не заработает. Для того, чтобы разобрать любой URL на составляющие его компоненты необходимо подключать в uses модуль WinInet в котором и содержится процедура internetcrackurl.
Теперь пройдем немного дальше. Взгляните ещё раз на таблицу соответствия. Как Вы можете заметить – она содержит расшифровку не всех цифр. Так, в таблице отсутствуют цифры: 1 и 3. Я не буду повторяться и дописывать недостающие элементы, а предложу Вам более красивый с точки зрения программистов вариант расшифровки.
Берем любое число и соответствующий ему код Captchaб например:
7 –> 1101112
Те, кто знаком с двоичной формой счисления, могут с первого взгляда определить, что в коде Captcha содержится число 7. Смотрите:
7 –> 11+0111+2
Открываем калькулятор, жмем кнопочку Bin, забиваем 0111, жмем кнопочку Dec и, о чудо, на табло высвечивается цифра 7!
Можете проверить всю таблицу таким образом – результат попадания в цель будет 100%. Теперь можно смело сократить код для расшифровки с семи до 4-х символов, т.е. отсечь первые 2 цифры – они всегда 11 и последнюю – она всегда 2. Теперь, ради спортивного интереса, можно получить семизначный код для недостающих элементов таблицы:
1 –> 1100012
3 –> 1100112
Теперь осталось написать функцию по переводу двоичного представления числа в десятеричную.
function BIN2DEC(BIN: string): LONGINT;
var
J: LONGINT;
Error: BOOLEAN;
DEC: LONGINT;
begin
DEC := 0;
Error := False;
for J := 1 to Length(BIN) do
begin
if (BIN[J] < > '0') and (BIN[J] < > '1') then
Error := True;
if BIN[J] = '1' then
DEC := DEC + (1 shl (Length(BIN) - J));
{ (1 SHL (Length(BIN) - J)) = 2^(Length(BIN)- J) }
end;
if Error then
BIN2DEC := 0
else
BIN2DEC := DEC;
end;
Весь секрет работы с двоичной системой заключается в теории, которую я, кстати почерпнул из книги “Нестандартные приемы программирования на Delphi”.
Теперь переписываем основную процедуру распознавания Captcha,используя полученные знания (в листинге представлена часть измененной процедуры):
function Captcha(URL: string):string;
var aURL: TURLComponents;
ParamStr: string; //строка, содержащая код каптчи
code: string; //7-ми значнй код из каптчи
i,j:integer;
begin
...
for I:=1 to 5 do //всего 35 цифр по 7 цифр на знак
begin
{получили 4-х значный код - двоичное представление числа}
code:=copy(copy(ParamStr,i+7*(i-1)-(i-1),7), 3, 4);
Result:=Result+BIN2DEC(Code); //вычислили число Captcha
end
...
end;
Вот и весь секрет слабой Captcha. И последнее, что хотелось бы сказать – это то, что врядли Вы когда-то встретите теперь в Интернете подобную систему защиты. Судя по тому, что из 50 каталогов сайтов, использующих эту систему защиты 50 мёртвых или переделанных, можно сделать однозначный вывод – время халявы кончилось :) Теперь Captcha стала на порядок сложнее для взлома.