PHP验证框 PHPZend360CacheF#
程序员文章站
2022-07-14 17:45:36
...
接触PHP一个星期了,boss要写一个图片验证框。在网上查了很多的资料,总结后得到如下最终的代码。以下代码生成的验证码有干扰条,干扰像素,字体旋转等。如果有不足的地方请回帖。
<?php header("Pragma: no-cache"); header("Cache-Control: max-age=1, s-maxage=1, no-cache, must-revalidate"); session_start(); unset ($_SESSION['validate']); $strnum = 8; //产生密码的位数 $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; //显示的字符范围 $font_file = 'Fregne Myriad v2.ttf';//指定字体文件 $disturbpiont = true; //是否显示干扰素 $disturbpiontnum = 600; //干扰素的点的数目 $disturbline = true; //是否有干扰条 $disturblinenum = 8; //干扰条的数目 $l = strlen($str); $randStr = array (); $validate; for ($i = 0; $i < $strnum; ++ $i) { $randStr[$i] = $str[rand(0, $l)]; } for ($i = 0; $i < $strnum; ++ $i) { if ($randStr[$i] == '') $randStr[$i] = '*'; $validate = $validate . $randStr[$i]; } function RgbToHsv($R, $G, $B) { $tmp = min($R, $G); $min = min($tmp, $B); $tmp = max($R, $G); $max = max($tmp, $B); $V = $max; $delta = $max - $min; if ($max != 0) $S = $delta / $max; // s else { $S = 0; return; } if ($R == $max) $H = ($G - $B) / $delta; // between yellow & magenta else if ($G == $max) $H = 2 + ($B - $R) / $delta; // between cyan & yellow else $H = 4 + ($R - $G) / $delta; // between magenta & cyan $H *= 60; // degrees if ($H < 0) $H += 360; return array ( $H, $S, $V ); } function HsvToRgb($H, $S, $V) { if ($S == 0) { // achromatic (grey) $R = $G = $B = $V; return; } $H /= 60; // sector 0 to 5 $i = floor($H); $f = $H - $i; // factorial part of h $p = $V * (1 - $S); $q = $V * (1 - $S * $f); $t = $V * (1 - $S * (1 - $f)); switch ($i) { case 0 : $R = $V; $G = $t; $B = $p; break; case 1 : $R = $q; $G = $V; $B = $p; break; case 2 : $R = $p; $G = $V; $B = $t; break; case 3 : $R = $p; $G = $q; $B = $V; break; case 4 : $R = $t; $G = $p; $B = $V; break; default : // case 5: $R = $V; $G = $p; $B = $q; break; } return array ( $R, $G, $B ); } $size = 30; $width = $size * $strnum +10; $height = $size +10; $degrees = array (); for ($i = 0; $i < $strnum; ++ $i) { $degrees[$i] = rand(0, 35); } // 生成数字旋转角度 for ($i = 0; $i < $strnum; ++ $i) { if (rand() % 2); else $degrees[$i] = - $degrees[$i]; } $image = imagecreatetruecolor($size, $size); // 数字图片画布 $validatepic = imagecreatetruecolor($width, $height); // 最终验证码画布 $back = imagecolorallocate($image, 255, 255, 255); // 背景色 $border = imagecolorallocate($image, 0, 0, 0); // 边框 imagefilledrectangle($validatepic, 0, 0, $width, $height, $back); // 画出背景色 // 数字颜色 for ($i = 0; $i < $strnum; ++ $i) { // 考虑为使字符容易看清使用颜色较暗的颜色 $temp = RgbToHsv(rand(0, 255), rand(0, 255), rand(0, 255)); if ($temp[2] > 60) $temp[2] = 60; $temp = HsvToRgb($temp[0], $temp[1], $temp[2]); $textcolor[$i] = imagecolorallocate($image, $temp[0], $temp[1], $temp[2]); } for ($i = 0; $i < $disturbpiontnum && $disturbpiont; ++ $i) //加入干扰象素 { $randpixelcolor = ImageColorallocate($validatepic, rand(0, 255), rand(0, 255), rand(0, 255)); imagesetpixel($validatepic, rand(1, $width -1), rand(1, $height -1), $randpixelcolor); } // 干扰线使用颜色较明亮的颜色 $temp = RgbToHsv(rand(0, 255), rand(0, 255), rand(0, 255)); if ($temp[2] < 200) $temp[2] = 255; $temp = HsvToRgb($temp[0], $temp[1], $temp[2]); $randlinecolor = imagecolorallocate($image, $temp[0], $temp[1], $temp[2]); // 画干扰线 for ($i = 0; $i < $disturblinenum && $disturbline; $i++) imageline($validatepic, rand(1, 239), rand(1, 39), rand(1, 239), rand(1, 39), $randpixelcolor); for ($i = 0; $i < $strnum; ++ $i) { $image = imagecreatetruecolor($size, $size); // 刷新画板 imagefilledrectangle($image, 0, 0, $size, $size, $back); // 画出背景色 imagefttext($image, 13, 0, 5, 20, $textcolor[$i], $font_file, $randStr[$i]); $image = imagerotate($image, $degrees[$i], $back); imagecolortransparent($image, $back); imagecopymerge($validatepic, $image, 5 + 30 * $i, 5, 0, 0, imagesx($image), imagesy($image), 100); } imagerectangle($validatepic, 0, 0, $width -1, $height -1, $border); // 画出边框 header('Content-type: image/png'); imagepng($validatepic); imagedestroy($validatepic); imagedestroy($image); $_SESSION['code'] = $validate;//将验证码存入session,如果实际应用,请md5. ?>
字体文件和该文件放在同一目录下即可,如果不是请设置
$font_file
需要设置背景颜色请修改
$back = imagecolorallocate($image, 255, 255, 255); // 背景色
显示图框的大小会随着设置显示的字符数变化。使用起来还是比较方便的。