diff options
author | lolcat <will@lolcat.ca> | 2025-08-11 01:55:15 +0000 |
---|---|---|
committer | lolcat <will@lolcat.ca> | 2025-08-11 01:55:15 +0000 |
commit | cdf958d29333d448f4521f4d2faa2592b58e9b27 (patch) | |
tree | 528f2a0ffa789a6f4279d9f54a4a2aaf391f390f /captcha.php | |
download | shittyweb-search-cdf958d29333d448f4521f4d2faa2592b58e9b27.tar.gz shittyweb-search-cdf958d29333d448f4521f4d2faa2592b58e9b27.tar.bz2 shittyweb-search-cdf958d29333d448f4521f4d2faa2592b58e9b27.zip |
fix wikipedia crashgrafted
Diffstat (limited to 'captcha.php')
-rwxr-xr-x | captcha.php | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/captcha.php b/captcha.php new file mode 100755 index 0000000..286a277 --- /dev/null +++ b/captcha.php @@ -0,0 +1,203 @@ +<?php + +if( + isset($_GET["v"]) === false || + is_array($_GET["v"]) === true || + preg_match( + '/^c[0-9]+\.[A-Za-z0-9_]{20}$/', + $_GET["v"] + ) === 0 +){ + + http_response_code(401); + header("Content-Type: text/plain"); + echo "Fuck my feathered cloaca"; + die(); +} + +//header("Content-Type: image/jpeg"); +include "data/config.php"; + +if(config::BOT_PROTECTION !== 1){ + + header("Content-Type: text/plain"); + echo "The IQ test is disabled"; + die(); +} + +$grid = apcu_fetch($_GET["v"]); + +if($grid !== false){ + + // captcha already generated + http_response_code(304); // not modified + die(); +} + +header("Content-Type: image/jpeg"); +header("Last-Modified: Thu, 01 Oct 1970 00:00:00 GMT"); + +// ** generate captcha data +// get the positions for the answers +// will return between 3 and 6 answer positions +$range = range(0, 15); +$answer_pos = []; + +array_splice($range, 0, 1); + +$picks = random_int(3, 6); + +for($i=0; $i<$picks; $i++){ + + $answer_pos_tmp = + array_splice( + $range, + random_int( + 0, + 14 - $i + ), + 1 + ); + + $answer_pos[] = $answer_pos_tmp[0]; +} + +// choose a dataset +$c = count(config::CAPTCHA_DATASET); +$choosen = config::CAPTCHA_DATASET[random_int(0, $c - 1)]; +$choices = []; + +for($i=0; $i<$c; $i++){ + + if(config::CAPTCHA_DATASET[$i][0] == $choosen[0]){ + + continue; + } + + $choices[] = config::CAPTCHA_DATASET[$i]; +} + +// generate grid data +$grid = []; + +for($i=0; $i<16; $i++){ + + if(in_array($i, $answer_pos)){ + + $grid[] = $choosen; + }else{ + + $grid[] = $choices[random_int(0, count($choices) - 1)]; + } +} + +// store grid data for form validation on captcha_gen.php +apcu_store( + $_GET["v"], + $answer_pos, + 60 // we give user 1 minute 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, 427, $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[$i][0] . "/" . random_int(1, $grid[$i][1]) . ".png"); + + // convert transparency correctly + $tmp->setImageBackgroundColor("black"); + $tmp->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE); + + // randomly mirror + if(random_int(0,1) === 1){ + + $tmp->flopImage(); + } + + // 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 + ); + + $tmp->addNoiseImage($noise[random_int(0, 1)]); + + // append image + $im->compositeImage($tmp->getImage(), Imagick::COMPOSITE_DEFAULT, $x * 100, ($y * 100) + 27); + + $i++; + } +} + +// add text +$draw = new ImagickDraw(); +$draw->setFontSize(20); +$draw->setFillColor($theme["fg"]); +//$draw->setTextAntialias(false); +$draw->setFont("./data/fonts/captcha.ttf"); + +$text = "Pick " . $picks . " images of " . str_replace("_", " ", $choosen[0]); + +$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); +echo $im->getImageBlob(); |