Advertisement
SirSpamModz

simple captcha

Aug 31st, 2017
337
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.20 KB | None | 0 0
  1. <?php
  2.  
  3. if(!defined('IS_INTERNAL')) { die('Direct file connect attempt.'); }
  4.  
  5. class captcha
  6. {
  7.     // Default bounds of a letter image
  8.     private static $image_default_bounds = [
  9.  
  10.         // Width
  11.         'w' => 30,
  12.  
  13.         // Height
  14.         'h' => 43,
  15.  
  16.         // w = (input_string_length + wp) * w
  17.         'wp' => 1,
  18.  
  19.         // Height padding.
  20.         'hp' => 23,
  21.     ];
  22.  
  23.     public static function GenerateCaptcha($user_id)
  24.     {
  25.         // Insert variables
  26.         $captcha_id = captcha::GenerateCapchaId();
  27.         $captcha_creator = $user_id;
  28.         $captcha_verification_text = cryptography::RandomString(config::GetConfig('CAPCHA_LENGTH'), false, false);
  29.         $captcha_image = GenerateImage($captcha_verification_text);
  30.         $captcha_entry_date = time();
  31.         $captcha_expiry = strtotime(config::GetConfig('CAPCHA_DURATION'));
  32.  
  33.         // Creating SQL instance
  34.         if(sql::Instance() === false) {
  35.             throw new Exception("SQL failed");
  36.         }
  37.  
  38.         // Is everything ok variable
  39.         $is_ok = true;
  40.  
  41.         // Inserting query
  42.         if($stmt = sql::Prepare("INSERT INTO `captchas` (`captcha_id`, `captcha_creator`, `captcha_verification_text`, `captcha_image`, `captcha_entry_date`, `captcha_expiry`, `enabled`) VALUES (?, ?, ?, ?, ?, ?, 'true')")) {
  43.             $stmt->bind_param('ssssii', $captcha_id, $captcha_creator, $captcha_verification_text, $captcha_image, $captcha_entry_date, $captcha_expiry);
  44.             $is_ok = $stmt->execute();
  45.             $stmt->close();
  46.         }
  47.         else {
  48.             throw new Exception("SQL prepare error");
  49.         }
  50.  
  51.         if($is_ok) {
  52.             return array(
  53.                 'success' => true,
  54.                 'response' => 'Captcha generated successfully',
  55.                 'data' => [
  56.                     'captcha_id' => $captcha_id,
  57.                     'captcha_creator' => $captcha_creator,
  58.                     'captcha_image' => $captcha_image,
  59.                     'captcha_expiry' => $captcha_expiry
  60.                 ]
  61.             );
  62.         }
  63.         else {
  64.             return array(
  65.                 'success' => false,
  66.                 'response' => 'Failed to generate Captcha.'
  67.             );
  68.         }
  69.     }
  70.  
  71.     public static function VerifyCaptcha($captcha_id, $user_input)
  72.     {
  73.         // Creating SQL instance
  74.         if(sql::Instance() === false) {
  75.             throw new Exception("SQL failed");
  76.         }
  77.  
  78.         // Is everything ok variable
  79.         $is_ok = true;
  80.         $is_valid = false;
  81.  
  82.         // Inserting query
  83.         if($stmt = sql::Prepare("SELECT * FROM `captchas` WHERE `captcha_id` = ?")) {
  84.             $stmt->bind_param('s', $captcha_id);
  85.             $is_ok = $stmt->execute();
  86.             $stmt->bind_result($captcha_id, $captcha_creator, $captcha_verification_text, $captcha_image, $captcha_entry_date, $captcha_expiry, $captcha_enabled);
  87.             $stmt->store_result();
  88.             $is_valid = $stmt->num_rows > 0;
  89.             $stmt->fetch();
  90.             $stmt->close();
  91.         }
  92.         else {
  93.             throw new Exception("SQL prepare error");
  94.         }
  95.  
  96.         if($is_ok) {
  97.  
  98.             // Checking row count
  99.             if(!$is_valid) {
  100.                 return [
  101.                     'success' => false,
  102.                     'response' => 'No captcha ID found'
  103.                 ];
  104.             }
  105.  
  106.             // Checking the expiry
  107.             if($captcha_expiry < time()) {
  108.                 return [
  109.                     'success' => false,
  110.                     'response' => 'Captcha expired'
  111.                 ];
  112.             }
  113.  
  114.             // Making sure the captcha is enabled.
  115.             if(misc::IsFalse($captcha_enabled)) {
  116.                 return [
  117.                     'success' => false,
  118.                     'response' => 'Captcha already been used'
  119.                 ];
  120.             }
  121.  
  122.             // Checking that the user input is valid
  123.             if($captcha_verification_text != $user_input) {
  124.                 return [
  125.                     'success' => false,
  126.                     'response' => 'Invalid input'
  127.                 ];
  128.             }
  129.  
  130.             // Disabling this captcha from working again
  131.             if($stmt = sql::Prepare("UPDATE `captchas` SET `enabled` = 'false' WHERE `captcha_id` = ?")) {
  132.                 $stmt->bind_param('s', $captcha_id);
  133.                 $is_ok = $stmt->execute();
  134.                 $stmt->close();
  135.             }
  136.             else {
  137.                 throw new Exception("SQL prepare error");
  138.             }
  139.  
  140.             if($is_ok) {
  141.                 return [
  142.                     'success' => true,
  143.                     'response' => 'Captcha is valid'
  144.                 ];
  145.             }
  146.             else {
  147.                 return [
  148.                     'success' => false,
  149.                     'response' => 'Internal error'
  150.                 ];
  151.             }
  152.         }
  153.         else {
  154.             return [
  155.                 'success' => false,
  156.                 'response' => 'Internal error'
  157.             ];
  158.         }
  159.     }
  160.  
  161.     /**
  162.     * Generates a captcha image from a text input.
  163.     *
  164.     * @param string $text The verification string that will be embeded in the image.
  165.     */
  166.     public static function GenerateImage($text)
  167.     {
  168.         // Generate bounds.
  169.         $generated_image_bounds['w'] = ((strlen($text) + captcha::$image_default_bounds['wp']) * captcha::$image_default_bounds['w']);
  170.         $generated_image_bounds['h'] = (captcha::$image_default_bounds['h'] + captcha::$image_default_bounds['hp']);
  171.  
  172.         // Variables to keep track of the x/y
  173.         $generated_image_current['x'] = 0;
  174.         $generated_image_current['y'] = 0;
  175.  
  176.         // Create image.
  177.         $generated_image = imagecreate(
  178.             $generated_image_bounds['w'],
  179.             $generated_image_bounds['h']
  180.         );
  181.  
  182.         // Going through each character.
  183.         for ($i = 0; $i < strlen($text); $i++) {
  184.             // Checking type of character.
  185.             if(is_numeric($text[$i])) {
  186.                 // Number character.
  187.  
  188.                 // Loading image.
  189.                 $image_file = "internal/images/".$text[$i].".png";
  190.                 $image_insert_temp = imagecreatefrompng($image_file);
  191.             }
  192.             else {
  193.                 // Normal character.
  194.  
  195.                 // There are two images for each letter, this is getting one of the two.
  196.                 if(rand(-50, 50) >= 0) {
  197.                     $rnd_letter_index = "1";
  198.                 }
  199.                 else {
  200.                     $rnd_letter_index = "2";
  201.                 }
  202.  
  203.                 //Loading image
  204.                 $image_file = "internal/images/".$text[$i]."-".$rnd_letter_index.".png";
  205.                 $image_insert_temp = imagecreatefrompng($image_file);
  206.             }
  207.  
  208.             // Generating random position to insert character into.
  209.             $generated_image_current['y'] = rand(0, $generated_image_bounds['h'] - captcha::$image_default_bounds['h']);
  210.             $generated_image_current['x'] += (($i == 0) ? 1 : rand(captcha::$image_default_bounds['w'], captcha::$image_default_bounds['w'] + captcha::$image_default_bounds['wp']));
  211.  
  212.             while($generated_image_current['x'] > $generated_image_bounds['w']) {
  213.                 $generated_image_current['x']--;
  214.             }
  215.  
  216.             // Inserting image to output image.
  217.             $image_copy = imagecopy(
  218.                 $generated_image,
  219.                 $image_insert_temp,
  220.  
  221.                 // dst
  222.                 $generated_image_current['x'],
  223.                 $generated_image_current['y'],
  224.  
  225.                 // scr
  226.                 0,
  227.                 0,
  228.                 captcha::$image_default_bounds['w'],
  229.                 captcha::$image_default_bounds['h']
  230.             );
  231.  
  232.             // Destroy image
  233.             imagedestroy($image_insert_temp);
  234.         }
  235.  
  236.         // Getting the image data
  237.         ob_start();
  238.         imagepng($generated_image);
  239.         $data = ob_get_contents();
  240.         ob_end_clean();
  241.  
  242.         // Destroy image
  243.         imagedestroy($generated_image);
  244.  
  245.         return base64_encode($data);
  246.     }
  247.  
  248.     /**
  249.     * Generates a random, unqiue, capcha id.
  250.     */
  251.     public static function GenerateCapchaId()
  252.     {
  253.         $len = config::GetConfig('CAPCHA_ID_LENGTH');
  254.         while(true) {
  255.             $id = cryptography::RandomId($len);
  256.             if(!captcha::DoesCapchaExist($id)) {
  257.                 break;
  258.             }
  259.         }
  260.         return $id;
  261.     }
  262.  
  263.     /**
  264.     * Checks if a capcha id exists.
  265.     *
  266.     * @param string $captcha_id The ID of the capcha.
  267.     */
  268.     public static function DoesCapchaExist($captcha_id)
  269.     {
  270.         if(sql::Instance() === false) {
  271.             throw new Exception("SQL failed");
  272.         }
  273.  
  274.         if($stmt = sql::Prepare('SELECT COUNT(*) FROM `captchas` WHERE `captcha_id` = ?')) {
  275.             $stmt->bind_param('s', $captcha_id);
  276.             $stmt->execute();
  277.             $stmt->bind_result($fetch_count);
  278.             $stmt->fetch();
  279.             $stmt->close();
  280.         }
  281.         else {
  282.             throw new Exception("SQL prepare error");
  283.         }
  284.  
  285.         return (isset($fetch_count) ? ($fetch_count > 0) : false);
  286.     }
  287. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement