欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PHP验证框 PHPZend360CacheF# 

程序员文章站 2022-07-14 17:50:18
...

接触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); // 背景色

显示图框的大小会随着设置显示的字符数变化。使用起来还是比较方便的。