PageRenderTime 56ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/scalr-2/tags/scalr-2.0.0/app/src/Lib/Graphics/Captcha/class.Captcha.php

http://scalr.googlecode.com/
PHP | 297 lines | 220 code | 23 blank | 54 comment | 12 complexity | 54ebed1dd6d57207da98bb476edbbc61 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, GPL-3.0
  1. <?php
  2. /******************************************************************
  3. Projectname: CAPTCHA 2
  4. Version: 0.9
  5. Author: Cristian Navalici cristian.navalici at gmail dot com
  6. Last modified: 22-feb-2007
  7. Copyright (C): 2007 Cristian Navalici, All Rights Reserved
  8. * GNU General Public License (Version 2, June 1991)
  9. *
  10. * This program is free software; you can redistribute
  11. * it and/or modify it under the terms of the GNU
  12. * General Public License as published by the Free
  13. * Software Foundation; either version 2 of the License,
  14. * or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will
  17. * be useful, but WITHOUT ANY WARRANTY; without even the
  18. * implied warranty of MERCHANTABILITY or FITNESS FOR A
  19. * PARTICULAR PURPOSE. See the GNU General Public License
  20. * for more details.
  21. Description:
  22. This class can generate CAPTCHAs, see README for more details!
  23. 28.02.2007 - added Windows specifications for MCRYPT_RAND
  24. ******************************************************************/
  25. class Captcha {
  26. // here you can make some adjustments
  27. private $font_size = 18; // if GD2 in points / GD1 in pixels
  28. private $font = 'fonts/Gibberish.ttf';
  29. private $img_height = 50;
  30. private $save_path = 'captcha'; // without trailing slash
  31. private $secret_key = 'JKHuioashdfiasjbnd';
  32. private $use_windows = 0; // 1 - if you'll use windows 0 - if don't
  33. // until here
  34. private $gd_enabled = true;
  35. private $allow_jpg_output = false;
  36. private $allow_png_output = false;
  37. private $length;
  38. //======================================================================
  39. // CONSTRUCTOR
  40. //======================================================================
  41. function __construct ($length = 6, $type = 'png', $letter = '') {
  42. $this->font = dirname(__FILE__)."/fonts/Gibberish.ttf";
  43. $check_gd = gd_info();
  44. if (!$check_gd['GD Version']) {
  45. $this->gd_enabled = false;
  46. }
  47. // check for JPG capability
  48. if ($check_gd['JPG Support']) {
  49. $this->allow_jpg_output = true;
  50. }
  51. // check for PNG capability
  52. if ($check_gd['PNG Support']) {
  53. $this->allow_png_output = true;
  54. }
  55. if(!session_id()){
  56. session_start();
  57. } else {
  58. session_regenerate_id();
  59. }
  60. }
  61. //======================================================================
  62. // MAIN FUNCTION: createCaptcha
  63. // create a captcha image based on supplied arguments
  64. // if GD is not enabled it switch to TEXT MODE
  65. //
  66. // @arg: $length (int) - length of generated string
  67. // $type (string) - type of generated picture (jpg or png)
  68. // $draw_lines (bool) - optional lines on picture
  69. // @return: none (picture saved)
  70. //======================================================================
  71. public function createCaptcha($length = 6, $type = 'png', $draw_lines = 'true') {
  72. if ($this->gd_enabled) {
  73. $img_length = $length * ($this->font_size+5);
  74. $image = imagecreatetruecolor($img_length, $this->img_height) or die("Cannot Initialize new GD image stream");;
  75. // ----- TRANSFORMATIONS PART -----------------------------------
  76. // set background
  77. $bgcolor = imagecolorallocate($image, 255, 255, 255);
  78. imagefill($image,0,0,$bgcolor);
  79. $random_pixels = $img_length * $this->img_height / 2;
  80. for ($i = 0; $i < $random_pixels; $i++) {
  81. $color_pixel = ImageColorAllocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
  82. ImageSetPixel($image, rand(0, $img_length), rand(0, $this->img_height), $color_pixel);
  83. }
  84. // smooth image
  85. imagefilter($image, IMG_FILTER_SMOOTH, 10);
  86. // add text
  87. $gens = $this->stringGenerator($length);
  88. for ($i = 0 ; $i < $length ; $i++)
  89. {
  90. $stringcolor = imagecolorallocate($image, mt_rand(0, 180), mt_rand(0, 100), mt_rand(0, 180));
  91. imagettftext($image, $this->font_size, mt_rand(-40,40), 10 + (($this->font_size + 4) * $i), mt_rand(20, 40),
  92. $stringcolor,
  93. $this->font,
  94. $gens[$i]);
  95. }
  96. // default draw lines
  97. if ((bool)$draw_lines) {
  98. $img = $this->drawLines ($image, $img_length);
  99. } else {
  100. $img = $image;
  101. }
  102. // ----- EOS TRANSFORMATIONS PART -----------------------------------
  103. //create name for saved files (must be unique)
  104. $sname = $this->save_path .'/'. substr(time(), -5);
  105. // if you want a jpeg or png but the option is not available
  106. // automated change to the other type
  107. if ((!$this->allow_jpg_output) && (!$this->allow_png_output)) {
  108. echo "We have a problem! We can't save jpg or png either. Check your GD configuration.";
  109. exit (0);
  110. } else {
  111. if ($type == 'jpeg') {
  112. if ($this->allow_jpg_output) {
  113. $sname .= '.jpg';
  114. imagejpeg($img, $sname);
  115. } else {
  116. $sname .= '.png';
  117. imagepng($img, $sname);
  118. }
  119. } elseif ($type == 'png') {
  120. if ($this->allow_png_output) {
  121. $sname .= '.png';
  122. imagepng($img, $sname);
  123. } else {
  124. $sname .= '.jpg';
  125. imagejpeg($img, $sname);
  126. }
  127. }
  128. } // if-else
  129. $_SESSION['savedfile'] = $sname;
  130. imagedestroy($img);
  131. } else {
  132. // if GD in not installed we switch to text mode
  133. echo $this->stringGenerator($length);
  134. }// ifelse ($gd_enabled)
  135. }
  136. //======================================================================
  137. // SHOW CAPTCHA
  138. // function to show captcha image on website page
  139. //
  140. // @arg: none
  141. // @return: echo image
  142. //======================================================================
  143. public function showCaptcha() {
  144. return "<img src='/" .$_SESSION['savedfile']. "' border='0' alt='captcha code' title='captcha code' />";
  145. }
  146. //======================================================================
  147. // VERIFY CAPTCHA
  148. //
  149. // @arg: $txt (string) - entered string from user
  150. // @return: bool (true / false)
  151. //======================================================================
  152. public function verifyCaptcha($txt) {
  153. // remove generated image
  154. if (is_file($_SESSION['savedfile'])) unlink ($_SESSION['savedfile']);
  155. // DECRYPTION PART
  156. $decrypted_data = $this->cryptDecrypt($_SESSION['captcha'], 'DECRYPT');
  157. return (strcmp ($txt, $decrypted_data) == 0) ? true : false;
  158. }
  159. //============================================================================================
  160. // P R I V A T E F U N C T I O N S
  161. //============================================================================================
  162. //======================================================================
  163. // STRING GENERATOR
  164. // generates a random string of alphanumerics for captcha
  165. //
  166. // @arg: $length (integer) - length of generated string
  167. // @return: $gen_string (string) - generated string (mixture of alphanumerics)
  168. //======================================================================
  169. private function stringGenerator($length) {
  170. // mix some letters and some digits
  171. $alphanumerics = array_merge(range('A', 'Z'), range(2, 9));
  172. $alphanumerics_len = count($alphanumerics) - 1;
  173. $gen_string = '';
  174. for ($i = 0; $i < $length; $i++) {
  175. $gen_string .= $alphanumerics[mt_rand(0, $alphanumerics_len)];
  176. }
  177. // ENCRYPTION PART
  178. $encrypted_data = $this->cryptDecrypt($gen_string, 'CRYPT');
  179. $_SESSION['captcha'] = $encrypted_data;
  180. return $gen_string;
  181. }
  182. //======================================================================
  183. // DRAW SOME LINES ON PICTURE
  184. // draw some lines to image to make it more complicated
  185. //
  186. // @arg: $image (resource)
  187. // $imagelength (int)
  188. // @return: $image (resource) - an image painted with lines
  189. //======================================================================
  190. private function drawLines($image, $imagelength) {
  191. for ($i =0 ; $i<4 ; $i++) {
  192. // define random colors for lines
  193. $cColor = imagecolorallocate($image,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
  194. // first coodinates are in the first half of image
  195. $x0coordonate = mt_rand (0, 0.5 * $imagelength);
  196. $y0coordonate = mt_rand (0, $this->img_height);
  197. // second coodinates are in the second half of image
  198. $x1coordonate = mt_rand (0.5 * $imagelength,$imagelength);
  199. $y1coordonate = mt_rand (0, $this->img_height);
  200. imageline ($image, $x0coordonate, $y0coordonate, $x1coordonate, $y1coordonate,$cColor );
  201. imageline ($image, $x0coordonate-1, $y0coordonate-1, $x1coordonate-1, $y1coordonate-1,$cColor );
  202. }
  203. return $image;
  204. }
  205. //======================================================================
  206. // CRYPT OR DECRYPT A STRING
  207. //
  208. // we encrypt the string with libmcrypt > 2.4.x
  209. // @arg: $txt (string) string in clear text
  210. // $flag (constant) CRYPT | DECRYPT
  211. // @return: $result (string) encoded string
  212. //======================================================================
  213. private function cryptDecrypt($txt, $flag) {
  214. $td = mcrypt_module_open('tripledes', '', 'ecb', '');
  215. // windows OS supports only MCRYPT_RAND
  216. if (!$this->use_windows) {
  217. $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_DEV_RANDOM);
  218. } else {
  219. srand ( ( (int) ( (double) microtime() * 1000003)) ); // good seed 1000003 is prime number
  220. $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
  221. }
  222. $ks = mcrypt_enc_get_key_size($td);
  223. $key = substr(md5($this->secret_key), 0, $ks);
  224. // Intialize encryption
  225. mcrypt_generic_init($td, $key, $iv);
  226. switch ($flag) {
  227. case 'CRYPT': $result = mcrypt_generic($td, $txt); break;
  228. case 'DECRYPT': $result = trim (mdecrypt_generic($td, $txt)); break;
  229. }
  230. // Terminate encryption handler
  231. mcrypt_generic_deinit($td);
  232. mcrypt_module_close($td);
  233. return $result;
  234. }
  235. } // EOF class
  236. ?>