php生成验证码类代码

  1. class securecode
  2. {
  3. private static $instance=null;
  4. private $code = '';
  5. private $fontfile;
  6. private $validate;
  7. private $image;
  8. private $specialadd = 'special string for securecode';
  9. private $codeexpire=86400;
  10. private $codecookiename='secure_code';
  11. /**
  12. * 构造方法
  13. */
  14. private function securecode()
  15. {
  16. $this->fontfile = dirname( __file__ ) . '/arial.ttf';
  17. }
  18. private function __construct()
  19. {
  20. $this->securecode();
  21. }
  22. public static function getinstance()
  23. {
  24. if (self::$instance==null)
  25. self::$instance=new self();
  26. return self::$instance;
  27. }
  28. /**
  29. * 指定字体文件所在路径,默认为当前文件夹下arial.ttf文件
  30. * @param $fontfile 文件路径
  31. * @return void
  32. */
  33. function loadfont($fontfile)
  34. {
  35. $this->fontfile = $fontfile;
  36. }
  37. /**
  38. * 图片输出方法,在执行本方法前程序不应该有任何形式的输出
  39. * @return void;
  40. */
  41. function stroke()
  42. {
  43. $this->savecode();
  44. self::sendheader();
  45. imagegif( $this->validate );
  46. imagedestroy( $this->validate );
  47. imagedestroy( $this->image );
  48. }
  49. /**
  50. * 图片保存方法
  51. * @param $filename 保存路径
  52. * @return void
  53. */
  54. function save($filename)
  55. {
  56. $this->savecode();
  57. imagegif( $this->validate , $filename );
  58. imagedestroy( $this->validate );
  59. imagedestroy( $this->image );
  60. }
  61. /**
  62. * 验证码验证方法
  63. * @param $input 要验证的字符串,即用户的输入内容
  64. * @return boolean 验证结果
  65. */
  66. function verify($input)
  67. {
  68. $input=strtolower($input);
  69. $targetcode=$this->authcode($input);
  70. $code=$this->getcookie();
  71. if (emptyempty($code)||$code!=$targetcode)
  72. $result= false;
  73. else
  74. $result=true;
  75. $_cookie[$this->codecookiename]='';
  76. setcookie ( $this->codecookiename, '', - 1 );
  77. return $result;
  78. }
  79. /**
  80. * 图片创建方法
  81. * @return void;
  82. */
  83. function createimage()
  84. {
  85. $this->randcode();
  86. $size = 30;
  87. $width = 90;
  88. $height = 35;
  89. $degrees = array (
  90. rand( 0 , 30 ), rand( 0 , 30 ), rand( 0 , 30 ), rand( 0 , 30 )
  91. );
  92. for ($i = 0; $i < 4; ++$i)
  93. {
  94. if (rand() % 2);
  95. else $degrees[$i] = -$degrees[$i];
  96. }
  97. $this->image = imagecreatetruecolor( $size , $size );
  98. $this->validate = imagecreatetruecolor( $width , $height );
  99. $back = imagecolorallocate( $this->image , 255 , 255 , 255 );
  100. $border = imagecolorallocate( $this->image , 0 , 0 , 0 );
  101. imagefilledrectangle( $this->validate , 0 , 0 , $width , $height , $back );
  102. for ($i = 0; $i < 4; ++$i)
  103. {
  104. $temp = self::rgbtohsv( rand( 0 , 250 ) , rand( 0 , 150 ) , rand( 0 , 250 ) );
  105. if ($temp[2] > 60) $temp[2] = 60;
  106. $temp = self::hsvtorgb( $temp[0] , $temp[1] , $temp[2] );
  107. $textcolor[$i] = imagecolorallocate( $this->image , $temp[0] , $temp[1] , $temp[2] );
  108. }
  109. for ($i = 0; $i < 200; ++$i)
  110. {
  111. $randpixelcolor = imagecolorallocate( $this->validate , rand( 0 , 255 ) , rand( 0 , 255 ) , rand( 0 , 255 ) );
  112. imagesetpixel( $this->validate , rand( 1 , 87 ) , rand( 1 , 35 ) , $randpixelcolor );
  113. }
  114. $temp = self::rgbtohsv( rand( 220 , 255 ) , rand( 220 , 255 ) , rand( 220 , 255 ) );
  115. if ($temp[2] < 200) $temp[2] = 255;
  116. $temp = self::hsvtorgb( $temp[0] , $temp[1] , $temp[2] );
  117. $randlinecolor = imagecolorallocate( $this->image , $temp[0] , $temp[1] , $temp[2] );
  118. self::imagelinethick( $this->validate , $textcolor[rand( 0 , 3 )] );
  119. imagefilledrectangle( $this->image , 0 , 0 , $size , $size , $back );
  120. putenv( 'gdfontpath=' . realpath( '.' ) );
  121. // name the font to be used (note the lack of the .ttf extension
  122. imagettftext( $this->image , 15 , 0 , 8 , 20 , $textcolor[0] , $this->fontfile , $this->code[0] );
  123. $this->image = imagerotate( $this->image , $degrees[0] , $back );
  124. imagecolortransparent( $this->image , $back );
  125. imagecopymerge( $this->validate , $this->image , 1 , 4 , 4 , 5 , imagesx( $this->image ) - 10 , imagesy( $this->image ) - 10 , 100 );
  126. $this->image = imagecreatetruecolor( $size , $size );
  127. imagefilledrectangle( $this->image , 0 , 0 , $size , $size , $back );
  128. imagettftext( $this->image , 15 , 0 , 8 , 20 , $textcolor[1] , $this->fontfile , $this->code[1] );
  129. $this->image = imagerotate( $this->image , $degrees[1] , $back );
  130. imagecolortransparent( $this->image , $back );
  131. imagecopymerge( $this->validate , $this->image , 21 , 4 , 4 , 5 , imagesx( $this->image ) - 10 , imagesy( $this->image ) - 10 , 100 );
  132. $this->image = imagecreatetruecolor( $size , $size );
  133. imagefilledrectangle( $this->image , 0 , 0 , $size - 1 , $size - 1 , $back );
  134. imagettftext( $this->image , 15 , 0 , 8 , 20 , $textcolor[2] , $this->fontfile , $this->code[2] );
  135. $this->image = imagerotate( $this->image , $degrees[2] , $back );
  136. imagecolortransparent( $this->image , $back );
  137. imagecopymerge( $this->validate , $this->image , 41 , 4 , 4 , 5 , imagesx( $this->image ) - 10 , imagesy( $this->image ) - 10 , 100 );
  138. $this->image = imagecreatetruecolor( $size , $size );
  139. imagefilledrectangle( $this->image , 0 , 0 , $size - 1 , $size - 1 , $back );
  140. imagettftext( $this->image , 15 , 0 , 8 , 20 , $textcolor[3] , $this->fontfile , $this->code[3] );
  141. $this->image = imagerotate( $this->image , $degrees[3] , $back );
  142. imagecolortransparent( $this->image , $back );
  143. imagecopymerge( $this->validate , $this->image , 61 , 4 , 4 , 5 , imagesx( $this->image ) - 10 , imagesy( $this->image ) - 10 , 100 );
  144. imagerectangle( $this->validate , 0 , 0 , $width - 1 , $height - 1 , $border );
  145. }
  146. /**
  147. * 获取随机生成的验证码
  148. * @return string 随机验证码,返回的验证码不进行任何处理
  149. */
  150. function getcode()
  151. {
  152. return $this->code;
  153. }
  154. /**
  155. * 生成随机码方法
  156. * @return void;
  157. */
  158. protected function randcode()
  159. {
  160. $alphastr = 'abcdefghijklmnpqrstuvwxyz123456789';
  161. $randstr = array (
  162. $alphastr{rand( 0 , 33 )}, $alphastr{rand( 0 , 33 )}, $alphastr{rand( 0 , 33 )}, $alphastr{rand( 0 , 33 )}
  163. );
  164. $this->code = strtolower( $randstr[0] . $randstr[1] . $randstr[2] . $randstr[3] );
  165. }
  166. /**
  167. * rgb色到hsv色转变方法
  168. * @param $r
  169. * @param $g
  170. * @param $b
  171. * @return array hsv数组
  172. */
  173. protected static function rgbtohsv($r, $g, $b)
  174. {
  175. $tmp = min( $r , $g );
  176. $min = min( $tmp , $b );
  177. $tmp = max( $r , $g );
  178. $max = max( $tmp , $b );
  179. $v = $max;
  180. $delta = $max - $min;
  181. if ($max != 0) $s = $delta / $max; // s
  182. else
  183. {
  184. $s = 0;
  185. //$h = undefinedcolor;
  186. return;
  187. }
  188. if ($r == $max) $h = ($g - $b) / $delta; // between yellow & magenta
  189. else if ($g == $max) $h = 2 + ($b - $r) / $delta; // between cyan & yellow
  190. else $h = 4 + ($r - $g) / $delta; // between magenta & cyan
  191. $h *= 60; // degrees
  192. if ($h < 0) $h += 360;
  193. return array (
  194. $h, $s, $v
  195. );
  196. }
  197. /**
  198. * 同上一方法功能相反
  199. * @param $h
  200. * @param $s
  201. * @param $v
  202. * @return array rgb数组
  203. */
  204. protected static function hsvtorgb($h, $s, $v)
  205. {
  206. if ($s == 0)
  207. {
  208. // achromatic (grey)
  209. $r = $g = $b = $v;
  210. return;
  211. }
  212. $h /= 60; // sector 0 to 5
  213. $i = floor( $h );
  214. $f = $h - $i; // factorial part of h
  215. $p = $v * (1 - $s);
  216. $q = $v * (1 - $s * $f);
  217. $t = $v * (1 - $s * (1 - $f));
  218. switch ($i)
  219. {
  220. case 0 :
  221. $r = $v;
  222. $g = $t;
  223. $b = $p;
  224. break;
  225. case 1 :
  226. $r = $q;
  227. $g = $v;
  228. $b = $p;
  229. break;
  230. case 2 :
  231. $r = $p;
  232. $g = $v;
  233. $b = $t;
  234. break;
  235. case 3 :
  236. $r = $p;
  237. $g = $q;
  238. $b = $v;
  239. break;
  240. case 4 :
  241. $r = $t;
  242. $g = $p;
  243. $b = $v;
  244. break;
  245. default : // case 5:
  246. $r = $v;
  247. $g = $p;
  248. $b = $q;
  249. break;
  250. }
  251. return array (
  252. $r, $g, $b
  253. );
  254. }
  255. /**
  256. * 使用cookie保存验证码的方法
  257. * @return void
  258. */
  259. protected function savecode()
  260. {
  261. $code = $this->authcode($this->code);
  262. $this->setcookie($code);
  263. }
  264. /**
  265. * 验证码cookie值获取方法
  266. * @return string cookie值
  267. */
  268. protected function getcookie()
  269. {
  270. if (emptyempty( $_cookie[$this->codecookiename] ))
  271. {
  272. return '';
  273. }
  274. else
  275. {
  276. return addslashes($_cookie[$this->codecookiename]);
  277. }
  278. }
  279. /**
  280. * 验证码cookie创建方法
  281. * @param string $code 要保存的验证码
  282. * @return void
  283. */
  284. protected function setcookie($code)
  285. {
  286. $expire = $this->codeexpire > 0 ? $this->codeexpire + time() : 0;
  287. setcookie( $this->codecookiename , $code, $expire );
  288. }
  289. /**
  290. * 验证码加密方法
  291. * @param string $code 要加密的随机码
  292. * @return mixed 执行结果
  293. */
  294. protected function authcode($code)
  295. {
  296. return md5($code.$this->specialadd);
  297. }
  298. /**
  299. * 干扰线生成方法
  300. * @param resource $image 图片资源句柄
  301. * @param string $color 干扰线颜色
  302. */
  303. protected static function imagelinethick($image, $color)
  304. {
  305. $k = rand( 5 , 20 );
  306. for ($px = 0; $px < 400; $px = $px + 1)
  307. {
  308. $y = $k * sin( 0.1 * ($px) ); //$y=200+10*sin(0.1*($px-200));
  309. for ($i = 0; $i < 2; $i++)
  310. {
  311. imagesetpixel( $image , $px , $y + 10 + $i , $color );
  312. }
  313. }
  314. }
  315. /**
  316. * http标头设置方法
  317. * @return void
  318. */
  319. protected static function sendheader()
  320. {
  321. header( "pragma: no-cache" );
  322. header( "cache-control: max-age=1, s-maxage=1, no-cache, must-revalidate" );
  323. header( 'content-type: image/gif' );
  324. }
  325. }//开源代码phpfensi.com