1

私は人々のためにウェブサイトを宣伝するPTCウェブサイトを運営しています。そして、ボットの使用を簡単に下げるか、完全に防ぐ必要があります。

広告カウンターのカウントダウンが完了したら、キャプチャをロードします。
しかし、私はあなたが何かを入力しなければならないキャプチャを望んでいません。マウスを1回クリックするだけです。

キャプチャをJavaScriptで実行できるとしたら、それは本当に素晴らしいことです。

私はこのようなものを探しています:

カウンター:0一致する番号を選択:7 [1] [0] [7] [2]

ユーザーは、番号と一致するボックス内の番号をクリックする必要があります。

数字は1〜9以内になります。

4

2 に答える 2

0

CAPTCHAスクリプトを作成しました。サイズ、文字数、選択する文字はカスタマイズ可能です。

ここにあるcaptcha.php

<?php
function generateCaptcha($num_digits, $challenge_num, $size, $chars, $incode = false) {
    if(session_id() == '') session_start();
    if(isset($_SESSION['captcha'])) unset($_SESSION['captcha']);
    // You *must* type your own random salt here, *DO NOT* use this one.
    $salt = 'H#(*h3^rh@(*E%h$W*WK#vMIv)%(D*(A&*W@A^D6@r4*I%u8tgsc#yejdi$d8dee';
    $message = '';
    if(isset($_POST['hash']) && isset($_POST['code'])) {
        if(!empty($_POST['hash']) && !empty($_POST['code']) && !empty($_POST['correct_index'])) {
            if(md5($_POST['hash'] . $_POST['code'] . $salt) == $_POST['correct_index']) {
                $message = '<p>Correct!</p>';
            } else {
                $message = 'Incorrect code. Please try again.';
            }
        }
    }
    $code = '';
    if($incode == false) {
        for($i = 0; $i < $num_digits; $i++) {
            $digit = substr($chars, floor(mt_rand(0, strlen($chars) - 1)), 1);
            while(strpos($code, "$digit") !== false) {
                $digit = substr($chars, floor(mt_rand(0, strlen($chars) - 1)), 1);
            }
            $code .= $digit;
        }
    } else {
        for($i = 0; $i < $num_digits; $i++) {
            $digit = substr($incode, floor(mt_rand(0, strlen($incode) - 1)), 1);
            while(strpos($code, "$digit") !== false) {
                $digit = substr($incode, floor(mt_rand(0, strlen($incode) - 1)), 1);
            }
            $code .= $digit;
        }
    }
    $parts = str_split($code);
    $width = $num_digits * $size;
    $height = $size * 2;
    $image = imagecreatetruecolor($width, $height);
    $background = imagecolorallocate($image, floor(mt_rand(96, 255)), floor(mt_rand(96, 255)), floor(mt_rand(96, 255)));
    imagefilledrectangle($image, 0, 0, $width, $height, $background);
    $num_spots = floor(mt_rand($size * 2, $size * 15));
    for($i = 0; $i < $num_spots; $i++) {
        $color = imagecolorallocate($image, floor(mt_rand(30, 255)), floor(mt_rand(30, 255)), floor(mt_rand(30, 255)));
        $x = floor(mt_rand(0, $width));
        $y = floor(mt_rand(0, $height));
        $ellipse_width = floor(mt_rand(0, $size / 2));
        $ellipse_height = floor(mt_rand(0, $size / 2));
        imagefilledellipse($image, $x, $y, $ellipse_width, $ellipse_height, $color);
        $x1 = floor(mt_rand(0, $width));
        $y1 = floor(mt_rand(0, $height));
        $x2 = floor(mt_rand(0, $width));
        $y2 = floor(mt_rand(0, $height));
        imageline($image, $x1, $y1, $x2, $y2, $color);
    }
    $num_dots = floor(mt_rand($size * 50, $size * 80));
    for($i = 0; $i < $num_dots; $i++) {
        $color = imagecolorallocate($image, floor(mt_rand(30, 255)), floor(mt_rand(30, 255)), floor(mt_rand(30, 255)));
        $x = floor(mt_rand(0, $width));
        $y = floor(mt_rand(0, $height));
        imagesetpixel($image, $x, $y, $color);
    }
    for($i = 0; $i < count($parts); $i++) {
        $color = imagecolorallocate($image, floor(mt_rand(0, 150)), floor(mt_rand(0, 150)), floor(mt_rand(0, 150)));
        $x = floor(mt_rand($size * 0.9, $size * 1.1));
        $y = floor(mt_rand($size, $size * 2));
        imagettftext($image, $size, floor(mt_rand(-10, 10)), $i * $x, $y, $color, 'Justus-Bold.ttf', $parts[$i]);
        imagettftext($image, $size, floor(mt_rand(-10, 10)), $i * $x + floor(mt_rand(1, 7)), $y, $color, 'Justus-Bold.ttf', $parts[$i]);
        imagettftext($image, $size, floor(mt_rand(-10, 10)), $i * $x + floor(mt_rand(1, 7)), $y, $color, 'Justus-Bold.ttf', $parts[$i]);
        imagettftext($image, $size, floor(mt_rand(-10, 10)), $i * $x + floor(mt_rand(1, 7)), $y, $color, 'Justus-Bold.ttf', $parts[$i]);
    }
    $white = imagecolorallocate($image, 255, 255, 255);
    $filename = md5(time() . $_SERVER['REMOTE_ADDR'] . mt_rand(0, 1000)) . '.png';
    imagepng($image, $filename);
    imagedestroy($image);
    $file = file_get_contents($filename);
    $imgsize = getimagesize($filename);
    unlink($filename);
    $captcha = 'data:' . $imgsize['mime'] . ';base64,' . base64_encode($file);
    $challenge = array('captcha' => '', 'code' => null, 'size' => 0, 'digits' => 0);
    if($incode == false) {
        $challenge = generateCaptcha($challenge_num, 0, $size, $chars, $code);
    }
    $hash = md5($challenge['code'] . $salt);
    $correct_index = array();
    for($i = 0; $i < strlen($challenge['code']); $i++) {
        $correct_index[] = strpos($code, substr($challenge['code'], $i, 1));
    }
    $result = array(
        'captcha' => $captcha,
        'challenge' => array($challenge['captcha'], $challenge['size'], $challenge['digits']),
        'size' => array($imgsize[0], $imgsize[1]),
        'hash' => $hash,
        'code' => $code,
        'message' => $message,
        'width' => $size,
        'digits' => $num_digits,
        'correct_index' => md5($hash . implode('', $correct_index) . $salt)
    );
    return $result;
}
?>

...そしてここにありますcaptcha.html

<!DOCTYPE HTML>
<!--
<?php
include 'captcha.php';
$captcha = generateCaptcha(4, 2, 100, '0123456789');
?>
-->
<html lang="en-US">
<head>
    <meta charset="UTF-8" />
    <title>Click-captcha test</title>
    <style type="text/css">
#challenge, #captcha-img {
    margin: 10px
}
#captcha-img {
    overflow: hidden
}
.captcha-digit {
    display: block;
    float: left;
    width: <?php echo $captcha['width']; ?>px;
    height: 100%;
    cursor: pointer
}
.captcha-digit-selected {
    background: #ccc;
    opacity: .75;
    filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr='#f2cccccc', EndColorStr='#f2cccccc')
}
    </style>
    <script type="text/javascript">
var captchaLinks = [];
var digits = [];
var num_digits = <?php echo $captcha['challenge'][2]; ?> - 1;
addEvent(window, 'load', init);
function init() {
    captchaLinks = ['<?php
$digits = array();
for($i = 'digit0'; $i < 'digit' . $captcha['digits']; $i++) {
    $digits[] = $i;
}
echo implode("', '", $digits);
?>'];
    for(var i = 0; i < captchaLinks.length; i++) {
    //for(var link in captchaLinks) {
        addEvent(document.getElementById(captchaLinks[i]), 'click', newCaptchaDigit);
    }
}
function newCaptchaDigit(e) {
        if(e.target.className == 'captcha-digit captcha-digit-selected') {
            digits.splice(digits.indexOf(e.target.id.substr(-1, 1)), 1);
            e.target.className = 'captcha-digit';
        } else if(digits.length <= num_digits) {
            digits.splice(num_digits, digits.length - num_digits, e.target.id.substr(-1, 1));
            e.target.className = 'captcha-digit captcha-digit-selected';
        }
        document.getElementById('code').value = digits.join('');
}
function addEvent(elem, event, handler) {
    if(elem !== null & typeof elem !== 'undefined') {
        if(elem.addEventListener) {
            elem.addEventListener(event, handler, false);
        } else if(elem.attachEvent) {
            elem.attachEvent('on' + event, handler);
        } else if(elem['on' + event]) {
            elem['on' + event] = handler;
        }
    }
}
    </script>
</head>
<body>
    <div>
        <form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">
            <div id="captcha">
                <div><?php echo $captcha['message']; ?></div>
                <div>Click the following number sequence:
                    <div id="challenge" style="width: <?php echo $captcha['challenge'][1][0]; ?>px; height: <?php echo $captcha['challenge'][1][1]; ?>px; background-image: url('<?php echo $captcha['challenge'][0]; ?>')"></div>
                </div>
                <div id="captcha-img" style="width: <?php echo $captcha['size'][0]; ?>px; height: <?php echo $captcha['size'][1]; ?>px; background-image: url('<?php echo $captcha['captcha']; ?>')">
<?php for($i = 'digit0'; $i < 'digit' . $captcha['digits']; $i++) { ?>
                    <a class="captcha-digit" id="<?php echo $i; ?>"></a>
<?php } ?>
                </div>
            </div>
            <input type="hidden" name="hash" value="<?php echo $captcha['hash']; ?>" />
            <input type="hidden" name="correct_index" value="<?php echo $captcha['correct_index']; ?>" />
            <input type="hidden" name="code" id="code" value="" />
            <input type="submit" value="Submit" />
        </form>
    </div>
</body>
</html>

何が起こっているのか見ていただければ幸いですが、ここで説明します。:-)

関数が呼び出されgenerateCaptcha、パラメータを受け取ります$num_digits, $challenge_num, $size, $chars, $incode = false


  • $num_digits: CAPTCHA に入れる文字数
  • $challenge_num: チャレンジに入れる文字数
  • $size: CAPTCHA のサイズ
  • $chars: 含める文字 (例: 数字の場合: '0123456789')
  • $incode: これは、チャレンジを生成するためにスクリプト自体が呼び出されたかどうかをスクリプトが判断できるようにするためです。設定しないでください。

したがって、4 文字、1 文字のチャレンジ (質問のような)、サイズ 30、数字のみの CAPTCHA 画像を作成するには、次のコードを使用します。

<?php
include 'captcha.php';
$captcha = generateCaptcha(4, 1, 30, '0123456789');
?>

次に、変数$captchaは次のようになります。

array(9) {
  ["captcha"]=>
  string(118058) "data:image/png;base64,iVBORw0KG...kSuQmCC"
  ["challenge"]=>
  array(3) {
    [0]=>
    string(76266) "data:image/png;base64,iVBORw0KG...kJggg=="
    [1]=>
    array(2) {
      [0]=>
      int(200)
      [1]=>
      int(200)
    }
    [2]=>
    int(2)
  }
  ["size"]=>
  array(2) {
    [0]=>
    int(400)
    [1]=>
    int(200)
  }
  ["hash"]=>
  string(32) "81bc501400b8da366e70b26007cb2323"
  ["code"]=>
  string(4) "4817"
  ["message"]=>
  string(0) ""
  ["width"]=>
  int(100)
  ["digits"]=>
  int(4)
  ["correct_index"]=>
  string(32) "17ae615be69c757505dc7f69fce2afb1"
}

さらに情報が必要な場合は、コメントで質問してください。

于 2012-08-09T10:11:55.073 に答える
0

完全なキャプチャがなければ、決心したボットを止めることはできません。

いくつかのアイデア。

10 分間に 10 ~ 15 のリクエストを許可します。それを超える場合は、キャプチャを要求するか、完全にブロックします。Cookie/セッションが機能しないため、これが IP ベースであることを確認してください

フォームに JavaScript を追加して、それがないと投稿できないようにします。ほとんどの電子メール収集スパム ボットは、javascript を実行せず、あきらめます。ランダムな文字列を生成し、ページ要求時に $_SESSION に保存します。JavaScript を使用して、フォームの投稿に追加します。その文字列が存在しない場合、フォーム ポストに一致するとキャプチャが表示されます。

または、javascript を使用してフォーム自体を構築します。

断固たるスクレーパーはほとんどのことを回避できますが、そうするためのコストを増やしたいだけです。

于 2012-08-06T22:50:41.037 に答える