diff options
Diffstat (limited to 'captcha.php')
-rwxr-xr-x | captcha.php | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/captcha.php b/captcha.php new file mode 100755 index 0000000..21da034 --- /dev/null +++ b/captcha.php @@ -0,0 +1,147 @@ +<?php + +if( + !isset($_GET["k"]) || + preg_match( + '/^c\.[0-9]+$/', + $_GET["k"] + ) +){ + + header("Content-Type: text/plain"); + echo "Fuck you"; + die(); +} + +header("Content-Type: image/jpeg"); + +$grid = apcu_fetch($_GET["k"]); + +if( + $grid === false || + $grid[3] === true // has already been generated +){ + + http_response_code(304); // not modified + die(); +} + +header("Last-Modified: Thu, 01 Oct 1970 00:00:00 GMT"); + +// only generate one captcha with this config +apcu_store( + $_GET["k"], + [ + $grid[0], + $grid[1], + $grid[2], + true // has captcha been generated? + ], + 120 // we give user another 2 minutes to solve +); + +// generate image + +if(random_int(0,1) === 0){ + + $theme = [ + "bg" => "#ebdbb2", + "fg" => "#1d2021" + ]; +}else{ + + $theme = [ + "bg" => "#1d2021", + "fg" => "#ebdbb2" + ]; +} + +$im = new Imagick(); +$im->newImage(400, 400, $theme["bg"]); +$im->setImageBackgroundColor($theme["bg"]); +$im->setImageFormat("jpg"); + +$noise = [ + imagick::NOISE_GAUSSIAN, + imagick::NOISE_LAPLACIAN +]; + +$distort = [ + imagick::DISTORTION_AFFINE, + imagick::DISTORTION_SHEPARDS +]; + +$i = 0; +for($y=0; $y<4; $y++){ + + for($x=0; $x<4; $x++){ + + $tmp = new Imagick("./data/captcha/" . $grid[0][$i][0] . "/" . random_int(1, $grid[0][$i][1]) . ".png"); + + // convert transparency correctly + $tmp->setImageBackgroundColor("black"); + $tmp->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE); + + // distort $tmp + $tmp->distortImage( + $distort[random_int(0,1)], + [ + 0, 0, + random_int(-15, 15), random_int(-15, 15), + + 100, 0, + random_int(80, 120), random_int(-15, 15), + + 100, 100, + random_int(80, 120), random_int(80, 120), + + 0, 100, + random_int(-15, 15), random_int(80, 120) + ], + false + ); + + // append image + $im->compositeImage($tmp->getImage(), Imagick::COMPOSITE_DEFAULT, $x * 100, $y * 100); + + $i++; + } +} + +// add noise +$im->addNoiseImage($noise[random_int(0, 1)]); + +// expand top of image +$im->setImageGravity(Imagick::GRAVITY_SOUTH); +$im->chopImage(0, -27, 400, 400); +$im->extentImage(0, 0, 0, -27); + +// add text +$draw = new ImagickDraw(); +$draw->setFontSize(20); +$draw->setFillColor($theme["fg"]); +//$draw->setTextAntialias(false); +$draw->setFont("./data/captcha/font.ttf"); + +$text = "Pick " . $grid[1] . " images of " . str_replace("_", " ", $grid[2]); + +$pos = 200 - ($im->queryFontMetrics($draw, $text)["textWidth"] / 2); + +for($i=0; $i<strlen($text); $i++){ + + $im->annotateImage( + $draw, + $pos, + 20, + random_int(-15, 15), + $text[$i] + ); + + $pos += $im->queryFontMetrics($draw, $text[$i])["textWidth"]; + +} + +$im->setFormat("jpeg"); +$im->setImageCompressionQuality(90); +$im->setImageCompression(Imagick::COMPRESSION_JPEG2000); +echo $im->getImageBlob(); |