Xwab
Форумыnavigate_nextПрограммирование на PHP

Мой алгоритм "Captcha"
Сообщения
Istsam

Начнем с того, что алгоритм использует базу данных.

[php:1:36d1de28af]
CREATE TABLE `captches` (
`captcha_id` INT(10) NOT NULL AUTO_INCREMENT,
`captcha_session_id` VARCHAR(50) NOT NULL,
`captcha_name` VARCHAR(255) NOT NULL,
`captcha_time` INT(10) NOT NULL,
PRIMARY KEY (`captcha_id`)
)
[/php:1:36d1de28af]

Из названий полей вытекает понятие, что в них будет храниться.

Создаем модель для работы с БД(в примере самая примитивная).

[php:1:36d1de28af]
class Captcha {
// key - int
public static function check($key){
if(mysql_num_rows(mysql_query('select captcha_id from captches where captcha_name = "'.$key.'"'))){
return true;
}else{
return false;
}
}
// key - int
public static function delete($key){
if(mysql_query('delete from captches where captcha_name = "'.$key.'"')){
return true;
}else{
return false;
}
}

}
[/php:1:36d1de28af]

Подключаем её(код своего загрузчика приводить не буду), обойдемся простым инклудом. Создавать экземпляры класса ми тому подобное - не надо.

Создаем отдельный файл(у меня он хранится в папке Modules/captcha/index.php).
[php:1:36d1de28af]
$width = 100;
$height = 60;
$font_size = 12.5;
$fon_let_amount = 30;
$path_fonts = $_SERVER['DOCUMENT_ROOT'].'/modules/captcha/fonts/';
$letters = 'nikita'; // сюда по сути, должна передаваться переменная
$colors = array('10','30','50','70','90','110','130','150','170','190','210');



$src = imagecreatetruecolor($width, $height);
$fon = imagecolorallocate($src, 255, 255, 255);
imagefill($src, 0, 0, $fon);

$fonts = array();
$dir = opendir($path_fonts);
while($fontName = readdir($dir)){
if($fontName != "." && $fontName != ".."){
$fonts[] = $fontName;
}
}
closedir($dir);

for($i = 0; $i < strlen($letters); $i++){
$color = imagecolorallocatealpha($src, rand(0,255), rand(0,255), rand(0,255), 100);
$font = $path_fonts.$fonts[rand(0, sizeof($fonts) - 1)];
$letter = $letters[(strlen($letters) - (strlen($letters)-$i))];
$size = rand($font_size - 2, $font_size + 2);
imagettftext($src, $size, rand(0, 45), rand($width * 0.1, $width - $width * 0.1), rand($height * 0.2, $height), $color, $font, $letter);
}

for($i=0;$i<strlen($letters);$i++){
$color = imagecolorallocatealpha($src, $colors[rand(0, sizeof($colors) - 1)], $colors[rand(0,sizeof($colors)-1)],$colors[rand(0,sizeof($colors)-1)],rand(20,40));
$font = $path_fonts.$fonts[rand(0,sizeof($fonts)-1)];
$letter = $letters[(strlen($letters) - (strlen($letters)-$i))];
$size = rand($font_size * 2.1 - 2, $font_size * 2.1 + 2);
$x = ($i + 1) * $font_size + rand(4,7);
$y = (($height * 2) / 3) + rand(0, 5);
$cod[] = $letter;
imagettftext($src, $size, rand(0, 15), $x, $y, $color, $font, $letter);
}

$_SESSION['secpic'] = implode('',$cod);

header ("Content-type: image/gif");
imagegif($src);
[/php:1:36d1de28af]

Алгоритм:

1.Генерируем специальной функцией(любой) уникальный код для капчи
2.Заносим его в базу и привязываем к сессии(captcha_session_id)

mysql_query("INSERT INTO captches SET
captcha_session_id = '".mysql_real_escape_string($_SESSION['session_id'])."',
captcha_name = '".$text_captcha."',
captcha_time = '".time()."'");

3.Удаляем из базы ненужный мусор( mysql_query("DELETE FROM captches WHERE captcha_time < '".(time() - 86400)."'") отсчет - сутки) (можно сделать это кроном)
4.Передаем переменную в капчу
5.Проверка
[php:1:36d1de28af]
<?php
if(!Captcha::check($key)){
$error[] = 'Ошибка. Капча не верна';
}
[/php:1:36d1de28af]

6.Если все прошло верно, удаляем из базы наш код( Captcha::delete($key) )

Жду дискуссий.
Прекрасно понимаю, что Вы сейчас кажете что мол прикрутить сюда можно что угодно, это всего лишь идея и возможно Вам захочется её развивать.
Прикрепил скриншот


__________
посл.ред. 18 Янв 2013, 12:21; всего 1 раз 18 Янв 2013, 12:12
Okula

Сделал бы пример капчи

18 Янв 2013, 12:20
m0ten

В чем фишка этой капчи?

18 Янв 2013, 12:22
Okula

Можно обойтись и без базы данных, только лишняя нагрузка идёт.

18 Янв 2013, 12:25
Istsam

Okula, ну я просто эксперементировал.
Пожалуйста, делайте как хотите.
Для новеньких интересно будет по размылшять

18 Янв 2013, 13:01
Fever

судя по алгоритму:

захожу я на страницу с капчей и обновляю её n-ое количество раз (попутно сохраняя код капчи с помощью antigate, к примеру), в результате у меня n-ое количество ключей, которые успешно пройдут ф-цию check.

Итог: подготовился и спамь до упаду.

18 Янв 2013, 14:04
Istsam

Fever, у меня например есть кроновский файл, который запускается каждые 4-5 минут. И чистит базу от ключей, по которым не прошли пользователи
Тем более, было бы что спамить. Способ все равно найдется

18 Янв 2013, 15:07
Okula

Istsam, кроном ты чистишь устаревшие ключи (после создания которых прошёл 1 день). За это время можно сохранить твою капчу и отправить её в распозновалку. Один фиг при следующем обновлении страницы капча выведется та же.

18 Янв 2013, 15:12
Istsam

Okula, нет, кроном я чищу все. В данном примере. за последние сутки. У меня же 4-5 минут.
Все, закрываю тему.

18 Янв 2013, 15:17
Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.