Просмотр файла libs/captcha.php

Размер файла: 9.83Kb
  1. <?php
  2.  
  3. # Серверный путь к сайту
  4. define('HOME', $_SERVER['DOCUMENT_ROOT']);
  5.  
  6. class KCAPTCHA {
  7. // generates keystring and image
  8. function KCAPTCHA() {
  9. ////////////////////////////////////////////////////////////
  10. // Настройки CAPTCHA //
  11. ////////////////////////////////////////////////////////////
  12. $alphabet = "0123456789";
  13. //$allowed_symbols = "0123456789";
  14. $allowed_symbols = "0123456789"; // Не ставить похожие символы (o=0, 1=l, i=j, t=f)
  15. $fontsdir = '/design/fonts/'; // папка с шрифтами
  16. $length = mt_rand(4, 5);
  17. $width = 100;
  18. $height = 50;
  19. $fluctuation_amplitude = 5;
  20. $no_spaces = true;
  21. $show_credits = false;
  22. $credits = '';
  23. $foreground_color = array (
  24. mt_rand(0, 100),
  25. mt_rand(0, 100),
  26. mt_rand(0, 100)
  27. );
  28. $background_color = array (
  29. mt_rand(200, 255),
  30. mt_rand(200, 255),
  31. mt_rand(200, 255)
  32. );
  33. $jpeg_quality = 90;
  34. ////////////////////////////////////////////////////////////
  35. $fonts = array ();
  36. $fontsdir_absolute = dirname(__FILE__) . '/' . $fontsdir;
  37. if ($handle = opendir($fontsdir_absolute)) {
  38. while (false !== ($file = readdir($handle))) {
  39. if (preg_match('/\.png$/i', $file)) {
  40. $fonts[] = $fontsdir_absolute . '/' . $file;
  41. }
  42. }
  43. closedir($handle);
  44. }
  45. $alphabet_length = strlen($alphabet);
  46. do {
  47. // generating random keystring
  48. while (true) {
  49. $this->keystring = '';
  50. for ($i = 0; $i < $length; $i++) {
  51. $this->keystring .= $allowed_symbols{mt_rand(0, strlen($allowed_symbols) - 1)};
  52. }
  53. if (!preg_match('/cp|cb|ck|c6|c9|rn|rm|mm|co|do|cl|db|qp|qb|dp|ww/', $this->keystring))
  54. break;
  55. }
  56. $font_file = $fonts[mt_rand(0, count($fonts) - 1)];
  57. $font = imagecreatefrompng($font_file);
  58. imagealphablending($font, true);
  59. $fontfile_width = imagesx($font);
  60. $fontfile_height = imagesy($font) - 1;
  61. $font_metrics = array ();
  62. $symbol = 0;
  63. $reading_symbol = false;
  64. // loading font
  65. for ($i = 0; $i < $fontfile_width && $symbol < $alphabet_length; $i++) {
  66. $transparent = (imagecolorat($font, $i, 0) >> 24) == 127;
  67. if (!$reading_symbol && !$transparent) {
  68. $font_metrics[$alphabet{$symbol}] = array ('start' => $i);
  69. $reading_symbol = true;
  70. continue;
  71. }
  72. if ($reading_symbol && $transparent) {
  73. $font_metrics[$alphabet{$symbol}]['end'] = $i;
  74. $reading_symbol = false;
  75. $symbol++;
  76. continue;
  77. }
  78. }
  79. $img = imagecreatetruecolor($width, $height);
  80. imagealphablending($img, true);
  81. $white = imagecolorallocate($img, 255, 255, 255);
  82. $black = imagecolorallocate($img, 0, 0, 0);
  83. imagefilledrectangle($img, 0, 0, $width - 1, $height - 1, $white);
  84. // draw text
  85. $x = 1;
  86. for ($i = 0; $i < $length; $i++) {
  87. $m = $font_metrics[$this->keystring{$i}];
  88. $y = mt_rand(-$fluctuation_amplitude, $fluctuation_amplitude) + ($height - $fontfile_height) / 2 + 2;
  89. if ($no_spaces) {
  90. $shift = 0;
  91. if ($i > 0) {
  92. $shift = 10000;
  93. for ($sy = 7; $sy < $fontfile_height - 20; $sy += 1) {
  94. for ($sx = $m['start'] - 1; $sx < $m['end']; $sx += 1) {
  95. $rgb = imagecolorat($font, $sx, $sy);
  96. $opacity = $rgb >> 24;
  97. if ($opacity < 127) {
  98. $left = $sx - $m['start'] + $x;
  99. $py = $sy + $y;
  100. if ($py > $height)
  101. break;
  102. for ($px = min($left, $width - 1); $px > $left - 12 && $px >= 0; $px -= 1) {
  103. $color = imagecolorat($img, $px, $py) & 0xff;
  104. if ($color + $opacity < 190) {
  105. if ($shift > $left - $px) {
  106. $shift = $left - $px;
  107. }
  108. break;
  109. }
  110. }
  111. break;
  112. }
  113. }
  114. }
  115. if ($shift == 10000) {
  116. $shift = mt_rand(4, 6);
  117. }
  118. }
  119. } else {
  120. $shift = 1;
  121. }
  122. imagecopy($img, $font, $x - $shift, $y, $m['start'], 1, $m['end'] - $m['start'], $fontfile_height);
  123. $x += $m['end'] - $m['start'] - $shift;
  124. }
  125. } while ($x >= $width - 10); // while not fit in canvas
  126. $center = $x / 2;
  127. // credits. To remove, see configuration file
  128. $img2 = imagecreatetruecolor($width, $height + ($show_credits ? 12 : 0));
  129. $foreground = imagecolorallocate($img2, $foreground_color[0], $foreground_color[1], $foreground_color[2]);
  130. $background = imagecolorallocate($img2, $background_color[0], $background_color[1], $background_color[2]);
  131. imagefilledrectangle($img2, 0, 0, $width - 1, $height - 1, $background);
  132. imagefilledrectangle($img2, 0, $height, $width - 1, $height + 12, $foreground);
  133. $credits = empty($credits) ? $_SERVER['HTTP_HOST'] : $credits;
  134. imagestring($img2, 2, $width / 2 - imagefontwidth(2) * strlen($credits) / 2, $height - 2, $credits, $background);
  135. // periods
  136. $rand1 = mt_rand(750000, 1200000) / 10000000;
  137. $rand2 = mt_rand(750000, 1200000) / 10000000;
  138. $rand3 = mt_rand(750000, 1200000) / 10000000;
  139. $rand4 = mt_rand(750000, 1200000) / 10000000;
  140. // phases
  141. $rand5 = mt_rand(0, 31415926) / 10000000;
  142. $rand6 = mt_rand(0, 31415926) / 10000000;
  143. $rand7 = mt_rand(0, 31415926) / 10000000;
  144. $rand8 = mt_rand(0, 31415926) / 10000000;
  145. // amplitudes
  146. $rand9 = mt_rand(330, 420) / 110;
  147. $rand10 = mt_rand(330, 450) / 110;
  148. //wave distortion
  149. for ($x = 0; $x < $width; $x++) {
  150. for ($y = 0; $y < $height; $y++) {
  151. $sx = $x + (sin($x * $rand1 + $rand5) + sin($y * $rand3 + $rand6)) * $rand9 - $width / 2 + $center + 1;
  152. $sy = $y + (sin($x * $rand2 + $rand7) + sin($y * $rand4 + $rand8)) * $rand10;
  153. if ($sx < 0 || $sy < 0 || $sx >= $width - 1 || $sy >= $height - 1) {
  154. continue;
  155. } else {
  156. $color = imagecolorat($img, $sx, $sy) & 0xFF;
  157. $color_x = imagecolorat($img, $sx + 1, $sy) & 0xFF;
  158. $color_y = imagecolorat($img, $sx, $sy + 1) & 0xFF;
  159. $color_xy = imagecolorat($img, $sx + 1, $sy + 1) & 0xFF;
  160. }
  161. if ($color == 255 && $color_x == 255 && $color_y == 255 && $color_xy == 255) {
  162. continue;
  163. } else if ($color == 0 && $color_x == 0 && $color_y == 0 && $color_xy == 0) {
  164. $newred = $foreground_color[0];
  165. $newgreen = $foreground_color[1];
  166. $newblue = $foreground_color[2];
  167. } else {
  168. $frsx = $sx - floor($sx);
  169. $frsy = $sy - floor($sy);
  170. $frsx1 = 1 - $frsx;
  171. $frsy1 = 1 - $frsy;
  172.  
  173. $newcolor = ($color * $frsx1 * $frsy1 + $color_x * $frsx * $frsy1 + $color_y * $frsx1 * $frsy + $color_xy * $frsx * $frsy);
  174. if ($newcolor > 255)
  175. $newcolor = 255;
  176. $newcolor = $newcolor / 255;
  177. $newcolor0 = 1 - $newcolor;
  178. $newred = $newcolor0 * $foreground_color[0] + $newcolor * $background_color[0];
  179. $newgreen = $newcolor0 * $foreground_color[1] + $newcolor * $background_color[1];
  180. $newblue = $newcolor0 * $foreground_color[2] + $newcolor * $background_color[2];
  181. }
  182. imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newred, $newgreen, $newblue));
  183. }
  184. }
  185. header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
  186. header('Cache-Control: no-store, no-cache, must-revalidate');
  187. header('Cache-Control: post-check=0, pre-check=0', FALSE);
  188. header('Pragma: no-cache');
  189. if (function_exists("imagejpeg")) {
  190. header("Content-Type: image/jpeg");
  191. imagejpeg($img2, null, $jpeg_quality);
  192. } else if (function_exists("imagegif")) {
  193. header("Content-Type: image/gif");
  194. imagegif($img2);
  195. } else if (function_exists("imagepng")) {
  196. header("Content-Type: image/x-png");
  197. imagepng($img2);
  198. }
  199. }
  200.  
  201. // returns keystring
  202. function getKeyString() { return $this->keystring; }
  203. }
  204.  
  205. // Обрабатываем запрос на картинку CAPTCHA
  206. session_name('sid');
  207. session_start();
  208. $captcha = new KCAPTCHA();
  209. $_SESSION['captcha'] = $captcha->getKeyString();
  210.  
  211. ?>