PageRenderTime 82ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/source/mods/admin/authcode.class.php

https://github.com/yfg2014/ddim
PHP | 710 lines | 432 code | 52 blank | 226 comment | 83 complexity | d33180457088158fcd601fc7457a70d7 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0
  1. <?php
  2. class authcode extends AuthCodes
  3. {
  4. public function check()
  5. {
  6. if(md5(strtoupper($_GET['checkcode'])) == $_SESSION['auth_code']){
  7. echo 1;
  8. }else{
  9. echo 0;
  10. }
  11. exit();
  12. }
  13. public function defshow()
  14. {
  15. /**
  16. * 这个页面用于生成验证码图像
  17. *
  18. * @author coolhpy <coolhpy@163.com>
  19. * @create 2006-6-17
  20. *
  21. * 2006-7-9 增加 PHP5 的支持
  22. */
  23. header("Cache-Control: no-cache, must-revalidate");
  24. // 定义验证码信息
  25. $arr['code'] = array(
  26. 'characters' => 'A-H,J-N,P-Z,1-9',
  27. 'length' => 4,
  28. 'deflect' => true,
  29. 'multicolor' => false
  30. );
  31. $this->setCode($arr['code']);
  32. // 定义干扰信息
  33. $arr['molestation'] = array(
  34. 'type' => 'line',
  35. 'density' => 'normal'
  36. );
  37. $this->setMolestation($arr['molestation']);
  38. // 定义图像信息. 设置图象类型请确认您的服务器是否支持您需要的类型
  39. $arr['image'] = array(
  40. 'type' => 'png',
  41. 'width' => 70,
  42. 'height' => 18
  43. );
  44. $this->setImage($arr['image']);
  45. // 定义字体信息
  46. $arr['font'] = array(
  47. 'space' => 3,
  48. 'size' => 12,
  49. 'file' => _APP_PATH."fonts/arial.ttf"
  50. );
  51. $this->setFont($arr['font']);
  52. // 定义背景色
  53. $arr['bg'] = array(
  54. 'r' => 255,
  55. 'g' => 255,
  56. 'b' => 255
  57. );
  58. $this->setBgColor($arr['bg']);
  59. // 输出到浏览器
  60. $this->paint();
  61. // 输出到文件, 文件名中不需要扩展名
  62. //$auth_code->paint('./test');
  63. die();
  64. }
  65. }
  66. /**
  67. * 这个类用于生成验证码图像, 同时可以对用户输入的验证码进行验证
  68. *
  69. * @author coolhpy <coolhpy@163.com>
  70. * @create 2006-6-17
  71. *
  72. * 2006-7-9 修正干扰象素的算法
  73. * 2006-10-22 修正了一些默认值。如果不设置验证码的位置,则默认为居中
  74. * 取消了对GIF的支持,因为 imagecreatetruecolor() 方法不支持
  75. */
  76. class AuthCodes
  77. {
  78. /**
  79. * 验证码
  80. * char: 字符
  81. * angle: 字符偏移的角度 (-30 <= angle <= 30)
  82. * color: 字符颜色
  83. *
  84. * @var array
  85. * @access private
  86. */
  87. var $code = array();
  88. /**
  89. * 字体信息
  90. * space: 字符间隔 (px)
  91. * size: 字体大小 (px)
  92. * left: 第一个字符距离图像最左边的象素 (px)
  93. * top: 字符距离图像最上边的象素 (px)
  94. * file: 字体文件的路径
  95. *
  96. * @var array
  97. * @access private
  98. */
  99. var $font = array();
  100. /**
  101. * 图像信息
  102. * type: 图像类型
  103. * mime: MIME 类型
  104. * width: 图像的宽 (px)
  105. * height: 图像高 (px)
  106. * func: 创建图像的方法
  107. *
  108. * @var array
  109. * @access private
  110. */
  111. var $image = array();
  112. /**
  113. * 干扰信息
  114. * type: 干扰类型 (False 表示不使用)
  115. * density: 干扰密度
  116. *
  117. * @var array
  118. * @access private
  119. */
  120. var $molestation = array();
  121. /**
  122. * 背景色 (RGB)
  123. * r: 红色 (0 - 255)
  124. * g: 绿色 (0 - 255)
  125. * b: 蓝色 (0 - 255)
  126. *
  127. * @var array
  128. * @access private
  129. */
  130. var $bg_color = array();
  131. /**
  132. * 默认前景色 (RGB)
  133. * r: 红色 (0 - 255)
  134. * g: 绿色 (0 - 255)
  135. * b: 蓝色 (0 - 255)
  136. *
  137. * @var array
  138. * @access private
  139. */
  140. var $fg_color = array();
  141. /**
  142. * Session 变量名
  143. *
  144. * @var string
  145. * @access private
  146. */
  147. var $session = '';
  148. /**
  149. * 构造函数
  150. *
  151. * @access public
  152. */
  153. function AuthCodes()
  154. {
  155. $this->setCode(null);
  156. $this->setMolestation(null);
  157. $this->setBgColor(null);
  158. $this->setImage(null);
  159. $this->setFont(null); // code, image 两部分必须在 font 之前定义
  160. $this->setSession('');
  161. }
  162. /**
  163. * 设置验证码
  164. *
  165. * @access public
  166. * @param array 字符信息
  167. * characters string 允许的字符
  168. * length int 验证码长度
  169. * deflect boolean 字符是否偏转
  170. * multicolor boolean 字符是否彩色
  171. * @return void
  172. */
  173. function setCode($code)
  174. {
  175. if (is_array($code))
  176. {
  177. if (!isset($code['characters']) || !is_string($code['characters']))
  178. {
  179. $code['characters'] = 'A-H,J-N,P-Z,1-9';
  180. }
  181. if (!(is_integer($code['length']) || $code['length']<=0))
  182. {
  183. $code['length'] = 4;
  184. }
  185. if (!is_bool($code['deflect']))
  186. {
  187. $code['deflect'] = true;
  188. }
  189. if (!is_bool($code['multicolor']))
  190. {
  191. $code['multicolor'] = false;
  192. }
  193. } else
  194. {
  195. $code = array('characters'=>'A-H,J-N,P-Z,1-9', 'length'=>4,
  196. 'deflect'=>true, 'multicolor'=>false);
  197. }
  198. $this->code = $code;
  199. }
  200. /**
  201. * 设置 session 变量名
  202. *
  203. * @access public
  204. * @param string session 变量名
  205. * @return void
  206. */
  207. function setSession($session)
  208. {
  209. if (isset($session) && !empty($session))
  210. {
  211. $this->session = $session;
  212. } else
  213. {
  214. $this->session = 'auth_code';
  215. }
  216. }
  217. /**
  218. * 设置背景色
  219. *
  220. * @access public
  221. * @param array RGB 颜色
  222. * @return void
  223. */
  224. function setBgColor($color)
  225. {
  226. if (is_array($color) && is_integer($color['r']) &&
  227. is_integer($color['g']) && is_integer($color['b']) &&
  228. ($color['r'] >= 0 && $color['r'] <= 255) &&
  229. ($color['g'] >= 0 && $color['g'] <= 255) &&
  230. ($color['b'] >= 0 && $color['b'] <= 255))
  231. {
  232. $this->bg_color = $color;
  233. } else
  234. {
  235. $this->bg_color = array('r'=>255,'g'=>255,'b'=>255);
  236. }
  237. // 设置默认的前景色, 与背景色相反
  238. $fg_color = array(
  239. 'r'=>255-$this->bg_color['r'],
  240. 'g'=>255-$this->bg_color['g'],
  241. 'b'=>255-$this->bg_color['b']
  242. );
  243. $this->setFgColor($fg_color);
  244. }
  245. /**
  246. * 设置干扰信息
  247. *
  248. * @access public
  249. * @param array 干扰信息
  250. * type string 干扰类型 (选项: false, 'point', 'line')
  251. * density string 干扰密度 (选项: 'normal', 'muchness', 'fewness')
  252. * @return void
  253. */
  254. function setMolestation($molestation)
  255. {
  256. if (is_array($molestation))
  257. {
  258. if (!isset($molestation['type']) ||
  259. ($molestation['type']!='point' &&
  260. $molestation['type']!='line' &&
  261. $molestation['type']!='both'))
  262. {
  263. $molestation['type'] = 'point';
  264. }
  265. if (!is_STRING($molestation['density']))
  266. {
  267. $molestation['density'] = 'normal';
  268. }
  269. $this->molestation = $molestation;
  270. } else
  271. {
  272. $this->molestation = array(
  273. 'type' => 'both',
  274. 'density' => 'normal'
  275. );
  276. }
  277. }
  278. /**
  279. * 设置字体信息
  280. *
  281. * @access public
  282. * @param array 字体信息
  283. * space int 字符间隔 (px)
  284. * size int 字体大小 (px)
  285. * left int 第一个字符距离图像最左边的象素 (px)
  286. * top int 字符距离图像最上边的象素 (px)
  287. * file string 字体文件的路径
  288. * @return void
  289. */
  290. function setFont($font)
  291. {
  292. if (is_array($font))
  293. {
  294. if (!is_integer($font['space']) || $font['space']<0)
  295. {
  296. $font['space'] = 5;
  297. }
  298. if (!is_integer($font['size']) || $font['size']<0)
  299. {
  300. $font['size'] = 12;
  301. }
  302. if (!is_integer($font['left']) || $font['left']<0 ||
  303. $font['left']>$this->image['width'])
  304. {
  305. $font['left'] = $this->image['width'] -
  306. ($font['size'] + $font['sapce'])
  307. * $this->code['length'] - $font['size'];
  308. }
  309. if (!is_integer($font['top']) || $font['top']<0 ||
  310. $font['top']>$this->image['height'])
  311. {
  312. $font['top'] = ($this->image['height'] - $font['size']) / 2
  313. + $font['size'];
  314. }
  315. if (!file_exists($font['file']))
  316. {
  317. $font['file'] = _APP_PATH."fonts/arial.ttf";
  318. }
  319. $this->font = $font;
  320. } else
  321. {
  322. $this->font = array('space'=>5, 'size'=>12,
  323. 'top'=>($this->image['height']-5),
  324. 'file'=>_APP_PATH."fonts/arial.ttf");
  325. $this->font['left'] = $this->image['width'] -
  326. ($this->font['size'] + $this->font['sapce'])
  327. * $this->code['length'] - $this->font['size'];
  328. $this->font['top'] = ($this->image['height'] - $this->font['size']) / 2
  329. + $this->font['size'];
  330. }
  331. }
  332. /**
  333. * 设置图像信息
  334. *
  335. * @access public
  336. * @param array 图像信息
  337. * type string 图像类型 (选项: 'png', 'wbmp', 'jpg')
  338. * width int 图像宽 (px)
  339. * height int 图像高 (px)
  340. * @return void
  341. */
  342. function setImage($image)
  343. {
  344. if (is_array($image))
  345. {
  346. if (!is_integer($image['width']) || $image['width'] <= 0)
  347. {
  348. $image['width'] = 70;
  349. }
  350. if (!is_integer($image['height']) || $image['height'] <= 0)
  351. {
  352. $image['height'] = 25;
  353. }
  354. $this->image = $image;
  355. $information = $this->getImageType($image['type']);
  356. if (is_array($information))
  357. {
  358. $this->image['mime'] = $information['mime'];
  359. $this->image['func'] = $information['func'];
  360. } else
  361. {
  362. $this->image['type'] = 'png';
  363. $information = $this->getImageType('png');
  364. $this->image['mime'] = $information['mime'];
  365. $this->image['func'] = $information['func'];
  366. }
  367. } else
  368. {
  369. $information = $this->getImageType('png');
  370. $this->image = array(
  371. 'type'=>'png',
  372. 'mime'=>$information['mime'],
  373. 'func'=>$information['func'],
  374. 'width'=>70,
  375. 'height'=>25);
  376. }
  377. }
  378. /**
  379. * 绘制图像
  380. *
  381. * @access public
  382. * @param string 文件名, 留空表示输出到浏览器
  383. * @return void
  384. */
  385. function paint($filename='')
  386. {
  387. // 创建图像
  388. $im = imagecreatetruecolor($this->image['width'],
  389. $this->image['height']);
  390. // 设置图像背景
  391. $bg_color = imagecolorallocate($im, $this->bg_color['r'],
  392. $this->bg_color['g'],
  393. $this->bg_color['b']);
  394. imagefilledrectangle($im, 0, 0, $this->image['width'],
  395. $this->image['height'], $bg_color);
  396. // 生成验证码相关信息
  397. $code = $this->generateCode();
  398. // 生成的验证码
  399. $the_code = '';
  400. // 向图像中写入字符
  401. $num = count($code);
  402. $current_left = $this->font['left'];
  403. $current_top = $this->font['top'];
  404. for ($i=0; $i<$num; $i++)
  405. {
  406. // $font_color = imagecolorallocate($im, rand(0,255),rand(0,255),rand(0,255));
  407. $font_color = imagecolorallocate($im, $code[$i]['color']['r'],
  408. $code[$i]['color']['g'],
  409. $code[$i]['color']['b']);
  410. imagettftext($im, $this->font['size'], $code[$i]['angle'],
  411. $current_left, $current_top, $font_color,
  412. $this->font['file'], iconv("gbk", "utf-8", $code[$i]['char']));
  413. $current_left += $this->font['size'] + $this->font['space'];
  414. $the_code .= $code[$i]['char'];
  415. }
  416. // 初始化 session
  417. // 如果 session 未启用, 则开启它
  418. if (empty($_SESSION['SID'])) @session_start();
  419. // 用 md5() 给密码加密, 写入 session
  420. $_SESSION[$this->session] = md5($the_code);
  421. $_SESSION[$this->session.'_none_case'] = md5(strtolower($the_code));
  422. //setcookie($this->session, md5($the_code), time()+60*5, "/");
  423. // setcookie($this->session.'_none_case', md5($the_code), time()+60*5, "/");
  424. //echo $this->session;
  425. // 绘制图像干扰
  426. $this->paintMolestation($im);
  427. // 输出
  428. if (isset($filename) && $filename!='')
  429. {
  430. $this->image['func']($im, $filename.$this->image['type']);
  431. } else
  432. {
  433. header("Cache-Control: no-cache, must-revalidate");
  434. header("Content-type: ".$this->image['mime']);
  435. $this->image['func']($im);
  436. }
  437. imagedestroy($im);
  438. }
  439. /**
  440. * 验证用户输入的验证码
  441. *
  442. * @param string 用户输入的字符串
  443. * @param boolean 是否区分大小写
  444. * @return boolean 正确返回 true
  445. */
  446. function validate($input, $is_match_case=true)
  447. {
  448. if ($is_match_case)
  449. {
  450. //return (strcmp($_SESSION[$this->session], md5($input)) == 0);
  451. return (strcmp($_COOKIE[$this->session], md5($input)) == 0);
  452. } else
  453. {
  454. return (strcmp($_COOKIE[$this->session.'_none_case'],
  455. md5(strtolower($input))) == 0);
  456. }
  457. }
  458. /**
  459. * 设置前景色
  460. *
  461. * @access private
  462. * @param array RGB 颜色
  463. * @return void
  464. */
  465. function setFgColor($color)
  466. {
  467. if (is_array($color) && is_integer($color['r']) &&
  468. is_integer($color['g']) && is_integer($color['b']) &&
  469. ($color['r'] >= 0 && $color['r'] <= 255) &&
  470. ($color['g'] >= 0 && $color['g'] <= 255) &&
  471. ($color['b'] >= 0 && $color['b'] <= 255))
  472. {
  473. $this->fg_color = $color;
  474. } else
  475. {
  476. $this->fg_color = array('r'=>0, 'g'=>0, 'b'=>0);
  477. }
  478. }
  479. /**
  480. * 生成随机验证码
  481. *
  482. * @access private
  483. * @return array 生成的验证码
  484. */
  485. function generateCode()
  486. {
  487. // 创建允许的字符串
  488. $array_allow = array();
  489. $characters = explode(',', $this->code['characters']);
  490. $num = count($characters);
  491. for ($i=0; $i<$num; $i++)
  492. {
  493. if (substr_count($characters[$i], '-') > 0)
  494. {
  495. $character_range = explode('-', $characters[$i]);
  496. for ($j=ord($character_range[0]); $j<=ord($character_range[1]);
  497. $j++)
  498. {
  499. $array_allow[] = chr($j);
  500. }
  501. } else
  502. {
  503. $array_allow[] = $array_allow[$i];
  504. }
  505. }
  506. $index = 0;
  507. while (list($key, $val) = each($array_allow))
  508. {
  509. $array_allow_tmp[$index] = $val;
  510. $index ++;
  511. }
  512. $array_allow = $array_allow_tmp;
  513. // 生成随机字符串
  514. mt_srand((double)microtime() * 1000000);
  515. $code = array();
  516. $index = 0;
  517. $i = 0;
  518. while ($i < $this->code['length'])
  519. {
  520. $index = mt_rand(0, count($array_allow) - 1);
  521. $code[$i]['char'] = $array_allow[$index];
  522. if ($this->code['deflect'])
  523. {
  524. $code[$i]['angle'] = mt_rand(-30, 30);
  525. } else
  526. {
  527. $code[$i]['angle'] = 0;
  528. }
  529. if ($this->code['multicolor'])
  530. {
  531. $code[$i]['color']['r'] = mt_rand(0, 255);
  532. $code[$i]['color']['g'] = mt_rand(0, 255);
  533. $code[$i]['color']['b'] = mt_rand(0, 255);
  534. } else
  535. {
  536. $code[$i]['color']['r'] = $this->fg_color['r'];
  537. $code[$i]['color']['g'] = $this->fg_color['g'];
  538. $code[$i]['color']['b'] = $this->fg_color['b'];
  539. }
  540. $i++;
  541. }
  542. return $code;
  543. }
  544. /**
  545. * 获取图像类型
  546. *
  547. * @access private
  548. * @param string 扩展名
  549. * @return [mixed] 错误时返回 false
  550. */
  551. function getImageType($extension)
  552. {
  553. switch (strtolower($extension))
  554. {
  555. case 'png':
  556. $information['mime'] = image_type_to_mime_type(IMAGETYPE_PNG);
  557. $information['func'] = 'imagepng';
  558. break;
  559. case 'wbmp':
  560. $information['mime'] = image_type_to_mime_type(IMAGETYPE_WBMP);
  561. $information['func'] = 'imagewbmp';
  562. break;
  563. case 'jpg':
  564. case 'jpeg':
  565. case 'jpe':
  566. $information['mime'] = image_type_to_mime_type(IMAGETYPE_JPEG);
  567. $information['func'] = 'imagejpeg';
  568. break;
  569. default:
  570. $information = false;
  571. }
  572. return $information;
  573. }
  574. /**
  575. * 绘制图像干扰
  576. *
  577. * @access private
  578. * @param resource 图像资源
  579. * @return void
  580. */
  581. function paintMolestation(&$im)
  582. {
  583. // 总象素
  584. $num_of_pels = ceil($this->image['width']*$this->image['height']/5);
  585. switch ($this->molestation['density'])
  586. {
  587. case 'fewness':
  588. $density = $num_of_pels / 3;
  589. break;
  590. case 'muchness':
  591. $density = $num_of_pels / 3 * 2;
  592. break;
  593. case 'normal':
  594. $density = $num_of_pels / 2;
  595. default:
  596. }
  597. switch ($this->molestation['type'])
  598. {
  599. case 'point':
  600. $this->paintPoints($im, $density);
  601. break;
  602. case 'line':
  603. $density = $density / 20;
  604. $this->paintLines($im, $density);
  605. break;
  606. case 'both':
  607. $density = $density / 2;
  608. $this->paintPoints($im, $density);
  609. $density = $density / 20;
  610. $this->paintLines($im, $density);
  611. break;
  612. default:
  613. break;
  614. }
  615. }
  616. /**
  617. * 画点
  618. *
  619. * @access private
  620. * @param resource 图像资源
  621. * @param int 点的数量
  622. * @return void
  623. */
  624. function paintPoints(&$im, $quantity)
  625. {
  626. mt_srand((double)microtime()*1000000);
  627. for ($i=0; $i<=$quantity; $i++)
  628. {
  629. $randcolor = imagecolorallocate($im, mt_rand(0,255),
  630. mt_rand(0,255), mt_rand(0,255));
  631. imagesetpixel($im, mt_rand(0, $this->image['width']),
  632. mt_rand(0, $this->image['height']), $randcolor);
  633. }
  634. }
  635. /**
  636. * 画线
  637. *
  638. * @access private
  639. * @param resource 图像资源
  640. * @param int 线的数量
  641. * @return void
  642. */
  643. function paintLines(&$im, $quantity)
  644. {
  645. mt_srand((double)microtime()*1000000);
  646. for ($i=0; $i<=$quantity; $i++)
  647. {
  648. $randcolor = imagecolorallocate($im, mt_rand(0,255),
  649. mt_rand(0,255), mt_rand(0,255));
  650. $x1 = mt_rand(0, $this->image['width']);
  651. $y1 = mt_rand(0, $this->image['height']);
  652. $x2 = $x1 + mt_rand(-30, 30);
  653. $y2 = $y1 + mt_rand(-30, 30);
  654. imageline($im, $x1, $y1, $x2, $y2, $randcolor);
  655. }
  656. }
  657. }
  658. ?>