Skip to content

Instantly share code, notes, and snippets.

@gmazzap
Last active July 8, 2017 11:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gmazzap/9977153 to your computer and use it in GitHub Desktop.
Save gmazzap/9977153 to your computer and use it in GitHub Desktop.
<?php
// require the class
@require_once __DIR__ . '/mycaptcha.php';
// defaults
$w = 110;
$h = 35;
$random_dots = 0;
$random_lines = 20;
$captcha_text_color = "0x#B9B098";
$captcha_noice_color = "0x#CEC7BA";
/* get code */
$code = filter_input( INPUT_GET, 'c', FILTER_SANITIZE_STRING );
if ( empty( $code ) ) die( '' );
$code = MyCaptcha::decode( $code );
/* get settings */
$sizes = filter_input( INPUT_GET, 'size', FILTER_SANITIZE_STRING );
if ( ! empty( $sizes ) ) {
$s = explode( 'x', $sizes );
if ( is_numeric($s[0]) && (int) $s[0] > 0 ) $w = (int) $s[0];
if ( isset($s[1]) && is_numeric($s[1]) && (int) $s[1] > 0 ) $h = (int) $s[1];
}
$dots = (int) filter_input( INPUT_GET, 'dots', FILTER_SANITIZE_NUMBER_INT );
if ( $dots > 0 ) $random_dots = $dots;
$lines = (int) filter_input( INPUT_GET, 'lines', FILTER_SANITIZE_NUMBER_INT );
if ( $dots > 0 ) $random_lines = $lines;
$tcolor = (string) filter_input( INPUT_GET, 'tcolor', FILTER_SANITIZE_STRING );
if ( strlen($tcolor) === 6 ) $captcha_text_color = "0x#{$tcolor}";
$ncolor = (string) filter_input( INPUT_GET, 'ncolor', FILTER_SANITIZE_STRING );
if ( strlen($ncolor) === 6 ) $captcha_noice_color = "0x#{$ncolor}";
/* prepare image */
$font = './monofont.ttf';
$font_size = $h * 0.75;
$image = @imagecreate($w, $h);
$bg_color = imagecolorallocate($image, 255, 255, 255);
$arr_text_color = MyCaptcha::hexrgb($captcha_text_color);
$text_color = imagecolorallocate(
$image,
$arr_text_color['red'],
$arr_text_color['green'],
$arr_text_color['blue']
);
$arr_noice_color = MyCaptcha::hexrgb($captcha_noice_color);
$image_noise_color = imagecolorallocate(
$image,
$arr_noice_color['red'],
$arr_noice_color['green'],
$arr_noice_color['blue']
);
/* generating dots randomly in background of image */
for( $i=0; $i < $random_dots; $i++ ) {
imagefilledellipse(
$image,
mt_rand(0, $w), mt_rand(0, $h),
2, 3,
$image_noise_color
);
}
/* generating lines randomly in background of image */
for( $i=0; $i < $random_lines; $i++ ) {
imageline(
$image,
mt_rand(0, $w), mt_rand(0, $h),
mt_rand(0, $w), mt_rand(0, $h),
$image_noise_color
);
}
/* create a text box and add 6 letters code in it */
$textbox = imagettfbbox( $font_size, 0, $font, $code );
$x = ( $w - $textbox[4] ) / 2;
$y = ( $h - $textbox[5] ) / 2;
imagettftext( $image, $font_size, 0, $x, $y, $text_color, $font , $code);
/* output captcha image */
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
<?php
class MyCaptcha {
protected $code = '';
protected $letters = '23456789bcdfghjkmnpqrstvwxyz';
protected $chars_num;
protected $tcolor;
protected $ncolor;
protected $width;
protected $height;
/**
* Allow to configure some options, generate a random code and print the fields
*/
function __construct( $args = array() ) {
$defaults = array(
'chars_num' => 6,
'dots' => 0,
'lines' => 20,
'width' => 110,
'height' => 35,
'tcolor' => 'B9B098',
'ncolor' => 'CEC7BA'
);
$args = wp_parse_args( $args, $defaults );
foreach ( $args as $k => $v ) {
$this->$k = $v;
}
$this->setCode();
$this->fields();
}
/**
* Print the fields
*/
protected function fields() {
echo $this->getHidden();
echo $this->getImg();
echo $this->getText();
}
/**
* Generate a random code
*/
protected function setCode() {
$i = 0;
$len = strlen( $this->letters ) - 1;
while ( $i < $this->chars_num ) {
$this->code .= substr( $this->letters, mt_rand( 0, $len ), 1 );
$i++;
}
}
/**
* Print hidden field
*/
protected function getHidden() {
return wp_nonce_field( $this->code , md5(__CLASS__) . '_n', FALSE, FALSE );
}
/**
* Print text field
*/
protected function getText() {
$f = '<label>%s<input type="text" name="%s" value="" autocomplete="off" /></label>';
return sprintf( $f, __('Type the captcha:', 'your-textdomain'), md5(__CLASS__) );
}
/**
* Print captcha image
*/
protected function getImg() {
$f = '<img src="%s" width="%d" height="%d" alt="" />';
$data = array(
'c' => self::encode( $this->code ),
'size' => "{$this->width}x{$this->height}",
'dots' => "{$this->dots}",
'lines' => "{$this->lines}",
'tcolor' => "{$this->tcolor}",
'ncolor' => "{$this->ncolor}"
);
$url = add_query_arg( $data, get_template_directory_uri() . '/captcha_img.php' );
return sprintf( $f, $url, $this->width, $this->height );
}
/**
* Verify the nonce
*/
static function verify() {
$method = filter_input( INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING );
$type = strtoupper( $method ) === 'GET' ? INPUT_GET : INPUT_POST;
$nonce = filter_input( $type, md5(__CLASS__) . '_n', FILTER_SANITIZE_STRING );
$code = filter_input( $type, md5(__CLASS__), FILTER_SANITIZE_STRING );
return ! empty($code) && ! empty($nonce) && wp_create_nonce( $code ) === $nonce;
}
/**
* Convert an hexadecimal color to an rgb array color
*/
static function hexrgb( $hex ) {
$int = hexdec( $hex );
return array(
"red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int
);
}
/**
* encode the code to avoid put plan code in image url
*/
private static function encode( $code ) {
$iv_size = mcrypt_get_iv_size( MCRYPT_BLOWFISH , MCRYPT_MODE_ECB );
$iv = mcrypt_create_iv( $iv_size, MCRYPT_RAND );
$key = md5( __CLASS__ );
$enc = mcrypt_encrypt( MCRYPT_BLOWFISH , $key, $code, MCRYPT_MODE_ECB, $iv);
return urlencode( base64_encode( $enc ) );
}
/**
* Decode the code
*/
static function decode( $encoded ) {
$code = urldecode( base64_decode( $encoded ) );
$iv_size = mcrypt_get_iv_size( MCRYPT_BLOWFISH , MCRYPT_MODE_ECB );
$iv = mcrypt_create_iv( $iv_size, MCRYPT_RAND );
$key = md5( __CLASS__ );
return mcrypt_decrypt( MCRYPT_BLOWFISH , $key, $code, MCRYPT_MODE_ECB, $iv );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment