<?
php
/*
*
* 这个类用于生成验证码图像, 同时可以对用户输入的验证码进行验证
*
* @author ♂bingo↗ [coolhpy@163.com]
* @since 2006-6-17
* @modify feifengxlq <feifengxlq@gmail.com> http://www.phpobject.net/blog
* @modify 2006-11-9
* 修改说明
*/
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
authcode
{
/*
*
* 验证码
* char: 字符
* angle: 字符偏移的角度 (-30 <= angle <= 30)
* color: 字符颜色
*
* @var array
* @access private
*/
var
$code
=
array
();
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 字体信息
* space: 字符间隔 (px)
* size: 字体大小 (px)
* left: 第一个字符距离图像最左边的象素 (px)
* top: 字符距离图像最上边的象素 (px)
* file: 字体文件的路径
*
* @var array
* @access private
*/
var
$font
=
array
();
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 图像信息
* type: 图像类型
* mime: MIME 类型
* width: 图像的宽 (px)
* height: 图像高 (px)
* func: 创建图像的方法
*
* @var array
* @access private
*/
var
$image
=
array
();
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 干扰信息
* type: 干扰类型 (false 表示不使用)
* density: 干扰密度
*
* @var array
* @access private
*/
var
$molestation
=
array
();
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 背景色 (RGB)
* r: 红色 (0 - 255)
* g: 绿色 (0 - 255)
* b: 蓝色 (0 - 255)
*
* @var array
* @access private
*/
var
$bg_color
=
array
();
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 默认前景色 (RGB)
* r: 红色 (0 - 255)
* g: 绿色 (0 - 255)
* b: 蓝色 (0 - 255)
*
* @var array
* @access private
*/
var
$fg_color
=
array
();
var
$authcode
=
''
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 构造函数,初始化各变量
*
* @access public
*/
function
__construct()
{
$this
->
setCode();
$this
->
setMolestation();
$this
->
setImage();
$this
->
setFont();
$this
->
setBgColor();
}
/*
*
* 获取产生的authcode
*/
function
getcode()
{
return
$this
->
authcode;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 绘制图像
*
* @access public
* @param string 文件名, 留空表示输出到浏览器
* @return void
*/
function
paint(
$filename
=
''
)
{
//
创建图像
$im
=
imagecreatetruecolor(
$this
->
image[
'
width
'
]
,
$this
->
image[
'
height
'
]);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
设置图像背景
$bg_color
=
imagecolorallocate(
$im
,
$this
->
bg_color[
'
r
'
]
,
$this
->
bg_color[
'
g
'
]
,
$this
->
bg_color[
'
b
'
]);
imagefilledrectangle(
$im
,
0
,
0
,
$this
->
image[
'
width
'
]
,
$this
->
image[
'
height
'
]
,
$bg_color
);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
生成验证码相关信息
$code
=
$this
->
generateCode();
//
向图像中写入字符
$num
=
count
(
$code
);
$current_left
=
$this
->
font[
'
left
'
];
$current_top
=
$this
->
font[
'
top
'
];
for
(
$i
=
0
;
$i
<
$num
;
$i
++
)
{
$font_color
=
imagecolorallocate(
$im
,
$code
[
$i
][
'
color
'
][
'
r
'
]
,
$code
[
$i
][
'
color
'
][
'
g
'
]
,
$code
[
$i
][
'
color
'
][
'
b
'
]);
imagettftext(
$im
,
$this
->
font[
'
size
'
]
,
$code
[
$i
][
'
angle
'
]
,
$current_left
,
$current_top
,
$font_color
,
$this
->
font[
'
file
'
]
,
$code
[
$i
][
'
char
'
]);
$current_left
+=
$this
->
font[
'
size
'
]
+
$this
->
font[
'
space
'
];
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
$the_code
.=
$code
[
$i
][
'
char
'
];
}
$this
->
authcode
=
$the_code
;
//
保存authcode
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
// 绘制图像干扰
$this
->
paintMolestation(
$im
);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
输出
if
(
isset
(
$filename
)
&&
$filename
!=
''
)
{
$this
->
image[
'
func
'
](
$im
,
$filename
.
$this
->
image[
'
type
'
]);
}
else
{
header
(
"
Cache-Control: no-cache, must-revalidate
"
);
header
(
"
Content-type:
"
.
$this
->
image[
'
mime
'
]);
$this
->
image[
'
func
'
](
$im
);
}
imagedestroy(
$im
);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 生成随机验证码
*
* @access private
* @return array 生成的验证码
*/
function
generateCode()
{
//
创建允许的字符串
$characters
=
explode
(
'
,
'
,
$this
->
code[
'
characters
'
]);
$num
=
count
(
$characters
);
for
(
$i
=
0
;
$i
<
$num
;
$i
++
)
{
if
(
substr_count
(
$characters
[
$i
]
,
'
-
'
)
>
0
)
{
$character_range
=
explode
(
'
-
'
,
$characters
[
$i
]);
for
(
$j
=
ord
(
$character_range
[
0
]);
$j
<=
ord
(
$character_range
[
1
]);
$j
++
)
{
$array_allow
[]
=
chr
(
$j
);
}
}
else
{
$array_allow
[]
=
$array_allow
[
$i
];
}
}
$index
=
0
;
while
(
list
(
$key
,
$val
)
=
each
(
$array_allow
))
{
$array_allow_tmp
[
$index
]
=
$val
;
$index
++
;
}
$array_allow
=
$array_allow_tmp
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
生成随机字符串
mt_srand
((
double
)
microtime
()
*
1000000
);
$code
=
array
();
$index
=
0
;
$i
=
0
;
while
(
$i
<
$this
->
code[
'
length
'
])
{
$index
=
mt_rand
(
0
,
count
(
$array_allow
)
-
1
);
$code
[
$i
][
'
char
'
]
=
$array_allow
[
$index
];
if
(
$this
->
code[
'
deflect
'
])
{
$code
[
$i
][
'
angle
'
]
=
mt_rand
(
-
30
,
30
);
}
else
{
$code
[
$i
][
'
angle
'
]
=
0
;
}
if
(
$this
->
code[
'
multicolor
'
])
{
$code
[
$i
][
'
color
'
][
'
r
'
]
=
mt_rand
(
0
,
255
);
$code
[
$i
][
'
color
'
][
'
g
'
]
=
mt_rand
(
0
,
255
);
$code
[
$i
][
'
color
'
][
'
b
'
]
=
mt_rand
(
0
,
255
);
}
else
{
$code
[
$i
][
'
color
'
][
'
r
'
]
=
$this
->
fg_color[
'
r
'
];
$code
[
$i
][
'
color
'
][
'
g
'
]
=
$this
->
fg_color[
'
g
'
];
$code
[
$i
][
'
color
'
][
'
b
'
]
=
$this
->
fg_color[
'
b
'
];
}
$i
++
;
}
return
$code
;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 获取图像类型
*
* @access private
* @param string 扩展名
* @return [mixed] 错误时返回 false
*/
function
getImageType(
$extension
)
{
switch
(
strtolower
(
$extension
))
{
case
'
png
'
:
$information
[
'
mime
'
]
=
image_type_to_mime_type
(IMAGETYPE_PNG);
$information
[
'
func
'
]
=
'
imagepng
'
;
break
;
case
'
gif
'
:
$information
[
'
mime
'
]
=
image_type_to_mime_type
(IMAGETYPE_GIF);
$information
[
'
func
'
]
=
'
imagegif
'
;
break
;
case
'
wbmp
'
:
$information
[
'
mime
'
]
=
image_type_to_mime_type
(IMAGETYPE_WBMP);
$information
[
'
func
'
]
=
'
imagewbmp
'
;
break
;
case
'
jpg
'
:
$information
[
'
mime
'
]
=
image_type_to_mime_type
(IMAGETYPE_JPEG);
$information
[
'
func
'
]
=
'
imagejpeg
'
;
break
;
case
'
jpeg
'
:
$information
[
'
mime
'
]
=
image_type_to_mime_type
(IMAGETYPE_JPEG);
$information
[
'
func
'
]
=
'
imagejpeg
'
;
break
;
case
'
jpe
'
:
$information
[
'
mime
'
]
=
image_type_to_mime_type
(IMAGETYPE_JPEG);
$information
[
'
func
'
]
=
'
imagejpeg
'
;
break
;
default
:
$information
=
false
;
}
return
$information
;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 绘制图像干扰
*
* @access private
* @param resource 图像资源
* @return void
*/
function
paintMolestation(
&
$im
)
{
//
总象素
$num_of_pels
=
ceil
(
$this
->
image[
'
width
'
]
*
$this
->
image[
'
height
'
]
/
5
);
switch
(
$this
->
molestation[
'
density
'
])
{
case
'
fewness
'
:
$density
=
ceil
(
$num_of_pels
/
3
);
break
;
case
'
muchness
'
:
$density
=
ceil
(
$num_of_pels
/
3
*
2
);
break
;
case
'
normal
'
:
$density
=
ceil
(
$num_of_pels
/
2
);
default
:
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
switch
(
$this
->
molestation[
'
type
'
])
{
case
'
point
'
:
$this
->
paintPoints(
$im
,
$density
);
break
;
case
'
line
'
:
$density
=
ceil
(
$density
/
30
);
$this
->
paintLines(
$im
,
$density
);
break
;
case
'
both
'
:
$density
=
ceil
(
$density
/
2
);
$this
->
paintPoints(
$im
,
$density
);
$density
=
ceil
(
$density
/
30
);
$this
->
paintLines(
$im
,
$density
);
break
;
default
:
break
;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 画点
*
* @access private
* @param resource 图像资源
* @param int 图像资源
* @return void
*/
function
paintPoints(
&
$im
,
$quantity
)
{
mt_srand
((
double
)
microtime
()
*
1000000
);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
for
(
$i
=
0
;
$i
<
$quantity
;
$i
++
)
{
$randcolor
=
imagecolorallocate(
$im
,
mt_rand
(
0
,
255
)
,
mt_rand
(
0
,
255
)
,
mt_rand
(
0
,
255
));
imagesetpixel(
$im
,
mt_rand
(
0
,
$this
->
image[
'
width
'
])
,
mt_rand
(
0
,
$this
->
image[
'
height
'
])
,
$randcolor
);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 画线
*
* @access private
* @param resource 图像资源
* @param int 图像资源
* @return void
*/
function
paintLines(
&
$im
,
$quantity
)
{
mt_srand
((
double
)
microtime
()
*
1000000
);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
for
(
$i
=
0
;
$i
<
$quantity
;
$i
++
)
{
$randcolor
=
imagecolorallocate(
$im
,
mt_rand
(
0
,
255
)
,
mt_rand
(
0
,
255
)
,
mt_rand
(
0
,
255
));
imageline(
$im
,
mt_rand
(
0
,
$this
->
image[
'
width
'
])
,
mt_rand
(
0
,
$this
->
image[
'
height
'
])
,
mt_rand
(
0
,
$this
->
image[
'
width
'
])
,
mt_rand
(
0
,
$this
->
image[
'
height
'
])
,
$randcolor
);
}
}
/*
*
* 设置前景色
*
* @access private
* @param array RGB 颜色
* @return void
*/
function
setFgColor(
$color
)
{
if
(
is_array
(
$color
)
&&
is_integer
(
$color
[
'
r
'
])
&&
is_integer
(
$color
[
'
g
'
])
&&
is_integer
(
$color
[
'
b
'
])
&&
(
$color
[
'
r
'
]
>=
0
&&
$color
[
'
r
'
]
<=
255
)
&&
(
$color
[
'
g
'
]
>=
0
&&
$color
[
'
g
'
]
<=
255
)
&&
(
$color
[
'
b
'
]
>=
0
&&
$color
[
'
b
'
]
<=
255
))
{
$this
->
fg_color
=
$color
;
}
else
{
$this
->
fg_color
=
array
(
'
r
'
=>
0
,
'
g
'
=>
0
,
'
b
'
=>
0
);
}
}
/*
*
* 设置验证码
*
* @access public
* @param array 字符信息
* characters string 允许的字符
* length int 验证码长度
* deflect boolean 字符是否偏转
* multicolor boolean 字符是否彩色
* @return void
*/
function
setCode(
$code
=
''
)
{
if
(
is_array
(
$code
))
{
if
(
!
isset
(
$code
[
'
characters
'
])
||
!
is_string
(
$code
[
'
characters
'
]))
{
$code
[
'
characters
'
]
=
'
0-9
'
;
}
if
(
!
(
is_integer
(
$code
[
'
length
'
])
||
$code
[
'
length
'
]
<=
0
))
{
$code
[
'
length
'
]
=
4
;
}
if
(
!
is_bool
(
$code
[
'
deflect
'
]))
{
$code
[
'
deflect
'
]
=
true
;
}
if
(
!
is_bool
(
$code
[
'
multicolor
'
]))
{
$code
[
'
multicolor
'
]
=
true
;
}
}
else
{
$code
=
array
(
'
characters
'
=>
'
0-9
'
,
'
length
'
=>
4
,
'
deflect
'
=>
true
,
'
multicolor
'
=>
false
);
}
$this
->
code
=
$code
;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 设置背景色
*
* @access public
* @param array RGB 颜色
* @return void
*/
function
setBgColor(
$color
=
''
)
{
if
(
is_array
(
$color
)
&&
is_integer
(
$color
[
'
r
'
])
&&
is_integer
(
$color
[
'
g
'
])
&&
is_integer
(
$color
[
'
b
'
])
&&
(
$color
[
'
r
'
]
>=
0
&&
$color
[
'
r
'
]
<=
255
)
&&
(
$color
[
'
g
'
]
>=
0
&&
$color
[
'
g
'
]
<=
255
)
&&
(
$color
[
'
b
'
]
>=
0
&&
$color
[
'
b
'
]
<=
255
))
{
$this
->
bg_color
=
$color
;
}
else
{
$this
->
bg_color
=
array
(
'
r
'
=>
255
,
'
g
'
=>
255
,
'
b
'
=>
255
);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
设置默认的前景色, 与背景色相反
$fg_color
=
array
(
'
r
'
=>
255
-
$this
->
bg_color[
'
r
'
]
,
'
g
'
=>
255
-
$this
->
bg_color[
'
g
'
]
,
'
b
'
=>
255
-
$this
->
bg_color[
'
b
'
]
);
$this
->
setFgColor(
$fg_color
);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 设置干扰信息
*
* @access public
* @param array 干扰信息
* type string 干扰类型 (选项: false, 'point', 'line')
* density string 干扰密度 (选项: 'normal', 'muchness', 'fewness')
* @return void
*/
function
setMolestation(
$molestation
=
''
)
{
if
(
is_array
(
$molestation
))
{
if
(
!
isset
(
$molestation
[
'
type
'
])
||
(
$molestation
[
'
type
'
]
!=
'
point
'
&&
$molestation
[
'
type
'
]
!=
'
line
'
&&
$molestation
[
'
type
'
]
!=
'
both
'
))
{
$molestation
[
'
type
'
]
=
'
point
'
;
}
if
(
!
is_string
(
$molestation
[
'
density
'
]))
{
$molestation
[
'
density
'
]
=
'
normal
'
;
}
$this
->
molestation
=
$molestation
;
}
else
{
$this
->
molestation
=
array
(
'
type
'
=>
'
point
'
,
'
density
'
=>
'
normal
'
);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 设置字体信息
*
* @access public
* @param array 字体信息
* space int 字符间隔 (px)
* size int 字体大小 (px)
* left int 第一个字符距离图像最左边的象素 (px)
* top int 字符距离图像最上边的象素 (px)
* file string 字体文件的路径
* @return void
*/
function
setFont(
$font
=
''
)
{
if
(
is_array
(
$font
))
{
if
(
!
is_integer
(
$font
[
'
space
'
])
||
$font
[
'
space
'
]
<
0
)
{
$font
[
'
space
'
]
=
5
;
}
if
(
!
is_integer
(
$font
[
'
size
'
])
||
$font
[
'
size
'
]
<
0
)
{
$font
[
'
size
'
]
=
12
;
}
if
(
!
is_integer
(
$font
[
'
left
'
])
||
$font
[
'
left
'
]
<
0
||
$font
[
'
left
'
]
>
$this
->
image[
'
width
'
])
{
$font
[
'
left
'
]
=
5
;
}
if
(
!
is_integer
(
$font
[
'
top
'
])
||
$font
[
'
top
'
]
<
0
||
$font
[
'
top
'
]
>
$this
->
image[
'
height
'
])
{
$font
[
'
top
'
]
=
$this
->
image[
'
height
'
]
-
5
;
}
if
(
!
file_exists
(
$font
[
'
file
'
]))
{
$font
[
'
file
'
]
=
'
./arial.ttf
'
;
}
$this
->
font
=
$font
;
}
else
{
$this
->
font
=
array
(
'
space
'
=>
5
,
'
size
'
=>
12
,
'
left
'
=>
5
,
'
top
'
=>
15
,
'
file
'
=>
'
./arial.ttf
'
);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
/*
*
* 设置图像信息
*
* @access public
* @param array 图像信息
* type string 图像类型 (选项: 'png', 'gif', 'wbmp', 'jpg')
* width int 图像宽 (px)
* height int 图像高 (px)
* @return void
*/
function
setImage(
$image
=
''
)
{
if
(
is_array
(
$image
))
{
if
(
!
is_integer
(
$image
[
'
width
'
])
||
$image
[
'
width
'
]
<=
0
)
{
$image
[
'
width
'
]
=
70
;
}
if
(
!
is_integer
(
$image
[
'
height
'
])
||
$image
[
'
height
'
]
<=
0
)
{
$image
[
'
height
'
]
=
20
;
}
$this
->
image
=
$image
;
$information
=
$this
->
getImageType(
$image
[
'
type
'
]);
if
(
is_array
(
$information
))
{
$this
->
image[
'
mime
'
]
=
$information
[
'
mime
'
];
$this
->
image[
'
func
'
]
=
$information
[
'
func
'
];
}
else
{
$this
->
image[
'
type
'
]
=
'
png
'
;
$information
=
$this
->
getImageType(
'
png
'
);
$this
->
image[
'
mime
'
]
=
$information
[
'
mime
'
];
$this
->
image[
'
func
'
]
=
$information
[
'
func
'
];
}
}
else
{
$information
=
$this
->
getImageType(
'
png
'
);
$this
->
image
=
array
(
'
type
'
=>
'
png
'
,
'
mime
'
=>
$information
[
'
mime
'
]
,
'
func
'
=>
$information
[
'
func
'
]
,
'
width
'
=>
70
,
'
height
'
=>
20
);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
?>
一个简单的使用例子:
<?
$auth_code = new AuthCode();
$auth_code->setImage(array('width'=>200,'height'=>20));
// 输出到浏览器
$auth_code->paint();
?>