[PHP] Текстовая капча
От: Volgare  
Дата: 01.06.15 16:05
Оценка:
У кого есть 5 минут, помогите с PHP, плиз.

Есть старая графическая капча, которую боты имеют на 1-2-3.
Решил поменять на текстовую. Будет задан вопрос, ответ на который знают только пользователи, например фамилия "Иванов". Ну и нужно проверить её после ввода юзером в поле.
Только фамилия может быть написана в транслите и разным регистром.
Сейчас имею это:
function prepare_captcha() {
    if (extension_loaded("gd")) {
        if (!session_id()) {
            session_start();
        }
    }
}

function show_captcha_image() {
    if (extension_loaded("gd")) {
        global $CAPTCHA_NUM;
        $CAPTCHA_NUM=mt_rand(0,100000);
        $tmp = "<img src=\"kcaptcha/index.php?".session_name()."=".session_id()."&amp;rnd=".mt_rand(0,1000000)."&amp;knum=".$CAPTCHA_NUM."\" border=\"0\" alt=\""._KCAPTCHA."\">";
        return $tmp;
    }
}

function show_captcha_field() {
    global $CAPTCHA_NUM;
    if (extension_loaded("gd")) {
        $tmp = "
            <input type=\"text\" name=\"keystring\" size=\"20\" maxlength=\"10\" autocomplete=\"off\">
            <input type=\"hidden\" name=\"knum\" value=\"".$CAPTCHA_NUM."\">
        ";
        return $tmp;
    }
}

function show_captcha_text() {
    if (extension_loaded("gd")) {
        $tmp = "<strong>"._KCAPTCHA.": </strong>&nbsp;&nbsp;";
        return $tmp;
    }
}

function valid_captcha() {    //return 1 if valid or 0 if invalid
    if (isset ($_POST['knum'])) {
        $knum=intval($_POST['knum']);
    }
    else {
        $knum=0;
    }
    if(isset($_SESSION['captcha_keystring_'.$knum]) && $_SESSION['captcha_keystring_'.$knum] == $_POST['keystring']) {
        foreach($_SESSION as $k=>$v) {
            if (strpos($k,'captcha')!==false) {
                unset($_SESSION[$k]);
            }
        }
        return 1;
    }
    else {
        foreach($_SESSION as $k=>$v) {
            if (strpos($k,'captcha')!==false) {
                unset($_SESSION[$k]);
            }
        }
        return 0;
    }
}
Re: [PHP] Текстовая капча
От: iPrior Россия darkmonk9@gmail.com
Дата: 02.06.15 05:35
Оценка: 6 (1)
Здравствуйте, Volgare, Вы писали:

V>У кого есть 5 минут, помогите с PHP, плиз.


V>Есть старая графическая капча, которую боты имеют на 1-2-3.

V>Решил поменять на текстовую. Будет задан вопрос, ответ на который знают только пользователи, например фамилия "Иванов". Ну и нужно проверить её после ввода юзером в поле.
V>Только фамилия может быть написана в транслите и разным регистром.

обязательно текстовую, может воспользоваться reCaptcha будет проще? — готовая библиотека так сказать.

Как я понимаю, алгоритм для текстовой, в виде вопрос-ответ, будет примерно следующий:
1. выискиваем вопрос из хранилища, с ответом
2. id вопроса в сессию (можно и ответ)
3. выводим вопрос
4. сравниваем ответ

ответ надо, как я понял, привести к единому виду — уменьшить все буквы (strtolower) и.... наверно перевести в транслит...
Re[2]: [PHP] Текстовая капча
От: Volgare  
Дата: 02.06.15 06:21
Оценка:
Здравствуйте, iPrior, Вы писали:

P>обязательно текстовую, может воспользоваться reCaptcha будет проще? — готовая библиотека так сказать.


Во-первых, эту рекапчу даже детективы угадывают со 2-3 раза. Меня она бесит. Проще 7 букв ввести.
Во-вторых, лишний раз проверить знания юзеров не помешает.

P>Как я понимаю, алгоритм для текстовой, в виде вопрос-ответ, будет примерно следующий:

P>1. выискиваем вопрос из хранилища, с ответом
P>2. id вопроса в сессию (можно и ответ)
P>3. выводим вопрос
P>4. сравниваем ответ

Знал бы я PHP хотя бы на уровне 2-го курса, то вопросов нет, реализовал бы этот алгоритм, а вчера потыкался — с первого раза не получилось, увы.

P>ответ надо, как я понял, привести к единому виду — уменьшить все буквы (strtolower) и.... наверно перевести в транслит...


Да можно в массиве два значения держать: русское и транслит. И по нему пройтись.
Re[3]: [PHP] Текстовая капча
От: iPrior Россия darkmonk9@gmail.com
Дата: 02.06.15 08:41
Оценка: 6 (1)
Здравствуйте, Volgare, Вы писали:

V>Знал бы я PHP хотя бы на уровне 2-го курса, то вопросов нет, реализовал бы этот алгоритм, а вчера потыкался — с первого раза не получилось, увы.


P>>ответ надо, как я понял, привести к единому виду — уменьшить все буквы (strtolower) и.... наверно перевести в транслит...


V>Да можно в массиве два значения держать: русское и транслит. И по нему пройтись.


интересно, где это "2-й курс"...?

думаю примерно так можно реализовать, без транслита
<?php
$captcha = [
    [
        'q' => 'Вопрос 1',
        'a' => 'Ответ 1'
    ],
    [
        'q' => 'Вопрос 2',
        'a' => 'Ответ 2'
    ]
    // ...
];

/**
 * Возвращает строку вопроса, сохраняя ID в сессию
 * @return string
 */
function getQuestion() {
    global $captcha;
    $k = rand(0, count($captcha));
    $_SESSION['captcha'] = $k;
    
    return $captcha[$k]['q'];
}

/**
 * Проверяет ответ пользователя на совпадение
 * @param string $userAnswerString
 * @return bool
 */
function validateAnswer($userAnswerString = '') {
    global $captcha;
    $isValid = false;
    if (array_key_exists('captcha', $_SESSION)) {
        $k = (int)$_SESSION['captcha'];
        
        if(array_key_exists($k, $captcha)) {
            $userAnswerString = trim(strtolower($userAnswerString));
            $answer = trim(strtolower($captcha[$k]['a']));
            $isValid = ($userAnswerString === $answer);
        }
    }
    
    return $isValid;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.