Просмотр файла shcms/antibot.php

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