-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathCaptcha.php
More file actions
executable file
·156 lines (147 loc) · 5.54 KB
/
Copy pathCaptcha.php
File metadata and controls
executable file
·156 lines (147 loc) · 5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php
// +----------------------------------------------------------------------
// | Buddy Framework
// +----------------------------------------------------------------------
// | Copyright (c) 2011 http://buddy.woshimaijia.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: xinqiyang <xinqiyang@gmail.com>
// +----------------------------------------------------------------------
/**
* Captcha Calss
* Captcha::instance('Captcha')->generate();
* generate png pic ,size: 88 * 32
* @author xinqiyang
*
*/
class Captcha extends Base
{
/**
* @var array Character sets
*/
static $V = array("a", "e", "d", "u", "y");
static $VN = array("a", "e", "d", "u", "y", "2", "3", "4", "5", "6", "7",
"8", "9");
static $C = array("b", "c", "d", "f", "g", "h", "a", "k", "m", "n", "p",
"q", "r", "s", "t", "u", "v", "w", "x", "z");
static $CN = array("b", "c", "d", "f", "g", "h", "a", "k", "m", "n", "p",
"q", "r", "s", "t", "u", "v", "w", "x", "z", "2", "3", "4", "5", "6", "7",
"8", "9");
private $_arrOption = array(
'fonts' => array('Candice.ttf','Ding-DongDaddyO.ttf','Duality.ttf','Jura.ttf'),
'fontsize' => 24,
'width' => 80,
'height' => 40,
'wordlen' => 4,
'suffix' => '.png',
'dotnoiselevel' => 100,
'linenoiselevel' => 5,
'usenumbers' => true,
'degree' => array(- 6, 6, 10, - 10, 12, - 12, 7, - 7),
);
/**
* construct
*
* @param array $arrOption
*/
public function __construct ($arrOption='')
{
if($arrOption)
{
$this->_arrOption = array_merge($this->_arrOption, array_intersect_key($arrOption,$this->_arrOption));
}
}
/**
* Generate captcha
*
* @return string captcha ID
*/
public function generate()
{
$strWord = $this->_generateWord();
$this->_generateImage($strWord);
//set the captcha session of the request
Session::set('captcha', $strWord);
return ;
}
/**
* generate word
* @return string generate words
*/
protected function _generateWord ()
{
$strWord = '';
$intWordLen = $this->_arrOption['wordlen'];
$arrVowels = $this->_arrOption['usenumbers'] ? self::$VN : self::$V;
$arrConsonants = $this->_arrOption['usenumbers'] ? self::$CN : self::$C;
for ($i = 0; $i < $intWordLen; $i = $i + 2) {
// generate word with mix of vowels and consonants
$strConsonants = $arrConsonants[array_rand($arrConsonants)];
$strVowels = $arrVowels[array_rand($arrVowels)];
$strWord .= $strConsonants . $strVowels;
}
if (strlen($strWord) > $intWordLen) {
$strWord = substr($strWord, 0, $intWordLen);
}
return $strWord;
}
/**
*
* generate image
* @param string $word Captcha word
*/
protected function _generateImage ($strWord)
{
if (! extension_loaded("gd")) {
throw new Exception(
"Image CAPTCHA requires GD extension");
}
if (! function_exists("imagepng")) {
throw new Exception(
"Image CAPTCHA requires PNG support");
}
if (! function_exists("imageftbbox")) {
throw new Exception(
"Image CAPTCHA requires FT fonts support");
}
$strFont = dirname(__FILE__).DIRECTORY_SEPARATOR.'Resource/'.$this->_arrOption['fonts'][array_rand($this->_arrOption['fonts'])];
if (empty($strFont)) {
throw new Exception("Image CAPTCHA requires font");
}
$intWidth = $this->_arrOption['width'];
$intHeight = $this->_arrOption['height'];
$intFontSize = $this->_arrOption['fontsize'];
$arrTextBox = imageftbbox($intFontSize, 0, $strFont, $strWord);
//adjust the h according to textbox
$intTextBoxWidth = abs($arrTextBox[2] - $arrTextBox[0]);
$intTextBoxHeight = abs($arrTextBox[7] - $arrTextBox[1]);
if ($intWidth < $intTextBoxWidth) {
$intWidth = $intTextBoxWidth;
}
if ($intTextBoxWidth > 0) {
$intHeight = ($intTextBoxHeight / $intTextBoxWidth) * $intWidth;
}
$resImage = imagecreatetruecolor($intWidth, $intHeight);
$intTextColor = imagecolorallocate($resImage, 0, 0, 0);
$intBgColor = imagecolorallocate($resImage, 255, 255, 255);
imagefilledrectangle($resImage, 0, 0, $intWidth - 1, $intHeight - 1, $intBgColor);
$intX = ($intWidth - $arrTextBox[2] - $arrTextBox[0]) / 2;
//$intX = rand(3, 6);
$intY = ($intHeight - $arrTextBox[7] - $arrTextBox[1]) / 2;
$intWordLen = strlen($strWord);
for ($i = 0; $i < $intWordLen; $i ++) {
$strLetter = $strWord[$i];
$intDegree = $this->_arrOption['degree'][array_rand($this->_arrOption['degree'])];
$arrCoords = imagefttext($resImage, $intFontSize + 4, $intDegree, $intX, $intY,
$intTextColor, $strFont, $strLetter);
$intX += ($arrCoords[2] - $intX) + (- 3);
}
//$resImage2 = $resImage;
header("Content-type: image/" . str_replace('.', '',
$this->_arrOption['suffix']));
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
imagepng($resImage);
imagedestroy($resImage);
}
}