追加オプションを選択してグラフィックキャプチャを作成する

画像



職場では、古いキャプチャがスパムボットによって簡単にバイパスされるため、スパムの問題を解決する必要がありました。 グーグルで正しいオプションを見つけられなかったので、私は自分自身を書くことにし、正直に言いたいと思っていました。



したがって、キャプチャの本質は、ユーザーがいくつかのアイコンを表示し、論理的に一般的な行に収まらないアイコンを選択する必要があるということです。 インターネットにはたくさんの選択肢があると思いますが、私はそれを見つけませんでした(正直なところ、私は実際に探していませんでした)。



始めましょう





操作の原則は次のとおりです。アイコンの2つのグループが組み立てられます。1つは正しいオプションの配列、もう1つは間違ったオプションの配列です。 共通の配列にアセンブルされますが、間違った画像のキー(配列要素のシリアル番号)はセッションに記録されます。

すべてのアイコンから1つの画像を収集し、それをbackground-positionを使用して切り取ります。

フォームは、1からアイコンの数までの値を持つラジオボタンです。 POSTを使用して、押された値でフォームを送信し、セッションに入れた数値と比較します。すべてが非常に簡単です。



そして、アイコンのグループが存在するディレクトリがあります:







すべての機能は1つのクラスに実装されます。 より詳細に分析します。



1.コンストラクターで記述された値を保存するためのいくつかのプライベート変数。




private $icon_dir; //,      private $icon_size; //  private $first_group_num; //    private $second_group_num; //    private $icon_count; //     private $group_count; //   private $address; //,     
      
      







2.実際には、4つのパラメーターが渡されるコンストラクター自体。




 function __construct($icons_count, $icon_dir, $icon_size, $address) { $this->icon_dir = $icon_dir; $this->icon_size = $icon_size; $this->group_count = scandir($this->icon_dir); $this->group_count = count($this->group_count) - 2; $this->first_group_num = rand(1, $this->group_count); $this->second_group_num = rand(1, $this->group_count); $this->icon_count = $icons_count; while ($this->first_group_num == $this->second_group_num) { $this->second_group_num = rand(1, $this->group_count); } $this->address = $address; }
      
      







3.正しいオプションと正しくないオプションのセットを使用すると、目的のオプションのセッションへの書き込みが次のように行われない限り、すべてが単純で通常のscandir()でアレイに書き込まれます。




 $_SESSION['iconcaptcha'] = array_search($true_icon, $array_of_icons) + 1;
      
      







ここで、$ true_iconは探しているアイコンで、$ array_of_iconsは最終的なアイコン配列です。



4.アイコンから最終画像を作成します。




 private function makeSprite() { //     $icons = array(); $array_of_icons = $this->getArrayOfIcons(); for ($i = 0; $i < $this->icon_count; ++$i) { $icons[] = imagecreatefrompng($array_of_icons[$i]); } //  png $tmp_sprite = imagecreatetruecolor($this->icon_count * $this->icon_size, $this->icon_size); imagealphablending($tmp_sprite, false); imagesavealpha($tmp_sprite, true); $tmp_icon = imagecreatetruecolor($this->icon_size, $this->icon_size); imagealphablending($tmp_icon, false); imagesavealpha($tmp_icon, true); foreach ($icons as $key => $val) { imagecopyresampled($tmp_icon, $val, 0, 0, 0, 0, $this->icon_size, $this->icon_size, $this->icon_size, $this->icon_size); imagecopy($tmp_sprite, $tmp_icon, $key * $this->icon_size, 0, 0, 0, imagesx($tmp_icon), imagesy($tmp_icon)); } header("Content-type: image/png"); imagepng($tmp_sprite); imagedestroy($tmp_sprite); exit; }
      
      







5.本格的な写真を作成するアドレスを取得します。




 private function getCaptchaAddress($address) { //    $address $req = end(explode('/', $_SERVER['REQUEST_URI'])); $req = explode('?', $req); if ($req[0] == $address) $this->makeSprite(); }
      
      







6.そして最後に、フォーム自体とすべてを推測する最終的な方法。 もちろん、ここでスタイルを削除する必要がありますが、 ここでbackground-imageが設定され、makeSprite()の呼び出しが引き起こされ、captchaが実際に作成されます(また、この曲がったメソッドでキャッシュの問題を解決します)。




 function getCaptchaForm() { $this->getCaptchaAddress($this->address); $captcha_form = '<style> #icon_captcha label div { background-image: url(/'.$this->address.'?'.rand().'); width: '.$this->icon_size.'px; height: '.$this->icon_size.'px; } #icon_captcha { margin-bottom: 20px !important; display: table !important; } #icon_captcha div { width: '.$this->icon_size.'px; display: inline-block; margin-right: 20px; } #icon_captcha div input { width: '.$this->icon_size.'px; margin-left: 0; float: left; border: none; } #icon_captcha div label img { border: none; } </style> <div id="icon_captcha">'; for ($i = 1; $i <= $this->icon_count; ++$i) { $captcha_form .= '<div> <label for="val_'.$i.'"> <div class="i'.$i.'" style="background-position: ' .(($i - 1)*(-$this->icon_size)). 'px 0;"></div> </label> <input type="radio" name="radio_val" id="val_'.$i.'" value="'.$i.'" /> </div>'; } $captcha_form .= '</div>'; return $captcha_form; }
      
      







呼び出しが1つの例でどのように見えるかを以下に示します。このことは構成ファイルで発生します。



 require(INC_DIR.'libs/IconCaptcha.class.php'); $icon_dir = $_SERVER['DOCUMENT_ROOT']."/design/site/images/captcha/"; $icon_captcha = new IconCaptcha(4, $icon_dir, 32, 'iconcaptcha'); $captcha_form = $icon_captcha->getCaptchaForm(); define('ICONCAPTCHA', $captcha_form);
      
      







次に、必要な形式でICONCAPTCHAを単純に置き換え、簡単な比較で確認します。$ _POST ['radio_val'] == $ _SESSION ['iconcaptcha']。



ここでデモをクリックできます: iconcaptcha.hut4.ru

ここでは、クラス全体を見ることができます: github.com/L1Qu0R/iconcaptcha/blob/master/IconCaptcha.class.php



All Articles