php 中文汉字验证码生成程序

这款关于php 中文汉字验证码生成程序其实很简单的,生成中文汉字验证码需要字体来支持了,下面我们用的arial.ttf来支持生成,否则生成中文图片验证码会出乱码的.

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. //开源代码phpfensi.com
  147. /**
  148. * 获取随机生成的验证码
  149. * @return string 随机验证码,返回的验证码不进行任何处理
  150. */
  151. function getcode()
  152. {
  153. return $this->code;
  154. }
  155. /**
  156. * 生成随机码方法
  157. * @return void;
  158. */
  159. protected function randcode()
  160. {
  161. $alphastr = 'abcdefghijklmnpqrstuvwxyz123456789';
  162. $randstr = array (
  163. $alphastr{rand( 0 , 33 )}, $alphastr{rand( 0 , 33 )}, $alphastr{rand( 0 , 33 )}, $alphastr{rand( 0 , 33 )}
  164. );
  165. $this->code = strtolower( $randstr[0] . $randstr[1] . $randstr[2] . $randstr[3] );
  166. }
  167. /**
  168. * rgb色到hsv色转变方法
  169. * @param $r
  170. * @param $g
  171. * @param $b
  172. * @return array hsv数组
  173. */
  174. protected static function rgbtohsv($r, $g, $b)
  175. {
  176. $tmp = min( $r , $g );
  177. $min = min( $tmp , $b );
  178. $tmp = max( $r , $g );
  179. $max = max( $tmp , $b );
  180. $v = $max;
  181. $delta = $max - $min;
  182. if ($max != 0) $s = $delta / $max; // s
  183. else
  184. {
  185. $s = 0;
  186. //$h = undefinedcolor;
  187. return;
  188. }
  189. if ($r == $max) $h = ($g - $b) / $delta; // between yellow & magenta
  190. else if ($g == $max) $h = 2 + ($b - $r) / $delta; // between cyan & yellow
  191. else $h = 4 + ($r - $g) / $delta; // between magenta & cyan
  192. $h *= 60; // degrees
  193. if ($h < 0) $h += 360;
  194. return array (
  195. $h, $s, $v
  196. );
  197. }
  198. /**
  199. * 同上一方法功能相反
  200. * @param $h
  201. * @param $s
  202. * @param $v
  203. * @return array rgb数组
  204. */
  205. protected static function hsvtorgb($h, $s, $v)
  206. {
  207. if ($s == 0)
  208. {
  209. // achromatic (grey)
  210. $r = $g = $b = $v;
  211. return;
  212. }
  213. $h /= 60; // sector 0 to 5
  214. $i = floor( $h );
  215. $f = $h - $i; // factorial part of h
  216. $p = $v * (1 - $s);
  217. $q = $v * (1 - $s * $f);
  218. $t = $v * (1 - $s * (1 - $f));
  219. switch ($i)
  220. {
  221. case 0 :
  222. $r = $v;
  223. $g = $t;
  224. $b = $p;
  225. break;
  226. case 1 :
  227. $r = $q;
  228. $g = $v;
  229. $b = $p;
  230. break;
  231. case 2 :
  232. $r = $p;
  233. $g = $v;
  234. $b = $t;
  235. break;
  236. case 3 :
  237. $r = $p;
  238. $g = $q;
  239. $b = $v;
  240. break;
  241. case 4 :
  242. $r = $t;
  243. $g = $p;
  244. $b = $v;
  245. break;
  246. default : // case 5:
  247. $r = $v;
  248. $g = $p;
  249. $b = $q;
  250. break;
  251. }
  252. return array (
  253. $r, $g, $b
  254. );
  255. }
  256. /**
  257. 使用cookie保存验证码的方法
  258. * @return void
  259. */
  260. protected function savecode()
  261. {
  262. $code = $this->authcode($this->code);
  263. $this->setcookie($code);
  264. }
  265. /**
  266. * 验证码cookie值获取方法
  267. * @return string cookie值
  268. */
  269. protected function getcookie()
  270. {
  271. if (emptyempty( $_cookie[$this->codecookiename] ))
  272. {
  273. return '';
  274. }
  275. else
  276. {
  277. return addslashes($_cookie[$this->codecookiename]);
  278. }
  279. }
  280. /**
  281. * 验证码cookie创建方法
  282. * @param string $code 要保存的验证码
  283. * @return void
  284. */
  285. protected function setcookie($code)
  286. {
  287. $expire = $this->codeexpire > 0 ? $this->codeexpire + time() : 0;
  288. setcookie( $this->codecookiename , $code, $expire );
  289. }
  290. /**
  291. * 验证码加密方法
  292. * @param string $code 要加密的随机码
  293. * @return mixed 执行结果
  294. */
  295. protected function authcode($code)
  296. {
  297. return md5($code.$this->specialadd);
  298. }
  299. /**
  300. * 干扰线生成方法
  301. * @param resource $image 图片资源句柄
  302. * @param string $color 干扰线颜色
  303. */
  304. protected static function imagelinethick($image, $color)
  305. {
  306. $k = rand( 5 , 20 );
  307. for ($px = 0; $px < 400; $px = $px + 1)
  308. {
  309. $y = $k * sin( 0.1 * ($px) ); //$y=200+10*sin(0.1*($px-200));
  310. for ($i = 0; $i < 2; $i++)
  311. {
  312. imagesetpixel( $image , $px , $y + 10 + $i , $color );
  313. }
  314. }
  315. }
  316. /**
  317. * http标头设置方法
  318. * @return void
  319. */
  320. protected static function sendheader()
  321. {
  322. header( "pragma: no-cache" );
  323. header( "cache-control: max-age=1, s-maxage=1, no-cache, must-revalidate" );
  324. header( 'content-type: image/gif' );
  325. }
  326. }