我是靠谱客的博主 娇气鸵鸟,这篇文章主要介绍特别简单的PHP验证码识别,现在分享给大家,希望可以做个参考。

本篇文章带大家介绍超简单的PHP验证码识别。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

有攻就有防

写这篇文章完全是因为同事的公众号发了一篇文章叫"实践-写个验证码",你简单写了一下,我就简单破解一下试试,生活处处有乐趣啊~

生成验证码

Copy代码,执行,生成如下验证码:

5726d767ec9b9624fb6707d8c71b76a.png

如图我们能发现,这个验证码格式特别"规范",字体大小一样,颜色都是黑色,让我们省了不少事儿。

二值化

程序读图,二值化(关键点在于查找字体颜色的阈值,这个验证码都是黑色,so...),通过程序一个像素点一个像素点判断,将属于字体颜色的标记为*,非字体颜色标记为0

57c523dfa6e8d003d42254e0f123ee2.png

<center>从上面的图,能够大概看出验证码的样子(YTAD)</center>

分析图像,切割

切割出字符串(先切绿线,再分别切蓝线,这样即使这个字符上下移动一下,也不太容易影响我们的切割)

c347ce726519d02e396dc195a0b951f.png

提取特征码

将字符串拆分后,我们多次获取验证码,将a-z,A-Z,0-9等验证码的特征码全部记录下来。

c90b1c6cfb1c587d10d6dbd8ae84856.png

<center>这个是提取出来的字母Y</center>

识别

识别的过程就是重复上面的:二值化->切割->提取特征码,再加上和之前提取的特征码比对相似度,就OK了。

PHP代码实现

复制代码
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/** * 简单验证码识别 * @author zhjx922 */ class vCode{ //字符特征码 private $_wordKeys = array ( 'A' => '000**00000****000**00**0**0000****0000****0000************0000****0000****0000**', 'B' => '******00**000**0**0000****000**0******00**000**0**0000****0000****000**0******00', 'C' => '00*****00**000****00000***000000**000000**000000**000000**00000*0**000**00*****0', 'D' => '******00**000**0**0000****0000****0000****0000****0000****0000****000**0******00', 'E' => '*********00000**00000**00000******0**00000**00000**00000**00000*******', 'F' => '**********000000**000000**000000******00**000000**000000**000000**000000**000000', 'G' => '00*****00**000****000000**000000**000000**000*****0000****0000**0**000**00*****0', 'H' => '**0000****0000****0000****0000************0000****0000****0000****0000****0000**', 'I' => '******00**0000**0000**0000**0000**0000**0000**0000**00******', 'J' => '00****0000**0000**0000**0000**0000**0000***000****0**00***00', 'K' => '**0000****000**0**00**00**0**000****0000****0000**0**000**00**00**000**0**0000**', 'L' => '**00000**00000**00000**00000**00000**00000**00000**00000**00000*******', 'M' => '**0000*****00*************0**0****0**0****0**0****0000****0000****0000****0000**', 'N' => '**0000*****000******00******00****0**0****0**0****00******000*****000*****0000**', 'P' => '*******0**0000****0000****0000*********0**000000**000000**000000**000000**000000', 'Q' => '00****000**00**0**0000****0000****0000****0000****0**0****00****0**00**000****0*', 'R' => '*******0**0000****0000****0000*********0*****000**00**00**000**0**0000****0000**', 'S' => '0******0**0000****000000**0000000******0000000**000000**000000****0000**0******0', 'T' => '********000**000000**000000**000000**000000**000000**000000**000000**000000**000', 'U' => '**0000****0000****0000****0000****0000****0000****0000****0000**0**00**000****00', 'V' => '**0000****0000****0000**0**00**00**00**00**00**000****0000****00000**000000**000', 'W' => '**0000****0000****0000****0000****0**0****0**0****0**0*************00*****0000**', 'X' => '**0000****0000**0**00**000****00000**000000**00000****000**00**0**0000****0000**', 'Y' => '**0000****0000**0**00**000****00000**000000**000000**000000**000000**000000**000', 'Z' => '*******00000**00000**0000**0000**0000**0000**0000**00000**00000*******', 'a' => '00*****00**000**000000**0*********0000****000***0****0**', 'b' => '**000000**000000**000000**0***00***00**0**0000****0000****0000*****00**0**0***00', 'c' => '00*****00**000****000000**000000**0000000**000**00*****0', 'd' => '000000**000000**000000**00***0**0**00*****0000****0000****0000**0**00***00***0**', 'e' => '00****000**00**0**0000************0000000**000**00*****0', 'f' => '000****000**00**00**00**00**000000**0000******0000**000000**000000**000000**0000', 'g' => '0*****0***000*****000**0**000**00*****00**0000000******0**0000**0******0', 'h' => '**000000**000000**000000**0***00***00**0**0000****0000****0000****0000****0000**', 'i' => '00**0000**000000000***0000**0000**0000**0000**0000**00******', 'k' => '**00000**00000**00000**00**0**0**00****000****000**0**00**00**0**000**', 'l' => '***00**00**00**00**00**00**00**00**0****', 'm' => '*0**0**0**0**0****0**0****0**0****0**0****0**0****0**0**', 'n' => '**0***00***00**0**0000****0000****0000****0000****0000**', 'o' => '00****000**00**0**0000****0000****0000**0**00**000****00', 'p' => '**0***00***00**0**0000****0000****0000*****00**0**0***00**000000**000000', 'q' => '00***0**0**00*****0000****0000****0000**0**00***00***0**000000**000000**', 'r' => '**0****00***00**0**000000**000000**000000**000000**00000', 's' => '0******0**0000****0000000******0000000****0000**0******0', 't' => '00**000000**0000******0000**000000**000000**000000**000000**00**000****0', 'u' => '**0000****0000****0000****0000****0000**0**00***00***0**', 'v' => '**0000****0000**0**00**00**00**000****0000****00000**000', 'w' => '**0000****0000****0**0****0**0****0**0**********0**00**0', 'x' => '**0000**0**00**000****00000**00000****000**00**0**0000**', 'y' => '**0000****0000****0000****0000****0000**0**00***00***0***00000**0******0', 'z' => '******0000**000**000**000**000**0000******', '0' => '000**00000****000**00**0**0000****0000****0000****0000**0**00**000****00000**000', '1' => '00**000***00****0000**0000**0000**0000**0000**0000**00******', '2' => '00****000**00**0**0000**000000**00000**00000**00000**00000**00000**00000********', '3' => '0*****00**000**0000000**00000**0000***0000000**0000000**000000****000**00*****00', '4' => '00000**00000***0000****000**0**00**00**0**000**0********00000**000000**000000**0', '5' => '*******0**000000**000000**0***00***00**0000000**000000****0000**0**00**000****00', '6' => '00****000**00**0**0000*0**000000**0***00***00**0**0000****0000**0**00**000****00', '7' => '********000000**000000**00000**00000**00000**00000**00000**00000**000000**000000', '8' => '00****000**00**0**0000**0**00**000****000**00**0**0000****0000**0**00**000****00', '9' => '00****000**00**0**0000****0000**0**00***00***0**000000**0*0000**0**00**000****00', ); /** * 生成验证码 * @author 武老师 */ public function make($verCode = '') { if(empty($verCode)) { $baseChars = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789'; $verCode = ''; $codeCharLenth = 4; for ($i = 1; $i <= $codeCharLenth; $i++) { // 通过字符串下标形式随机获取 $verCode .= $baseChars{mt_rand(0, strlen($baseChars) - 1)}; } } // 以下代码是将生成的验证码生成图片 $font_size = 20; $width = 60; $height = 30; $img = imagecreate($width, $height); // 新建一个基于调色板的图像 $bgR = mt_rand(50, 200); //r(ed) $bgG = mt_rand(50, 200); //g(reen) $bgB = mt_rand(50, 200); //b(lue) $background = imagecolorallocate($img, $bgR, $bgG, $bgB); // 背景色 $black = imagecolorallocate($img, 0, 0, 0); imagestring($img, 5, 9, 8, $verCode, $black); // 水平地画一行字符串 ob_start(); imagepng($img); $image = ob_get_contents(); ob_end_clean(); return array( 'image' => $image, 'code' => $verCode ); } /** * 获取原始图像数组 * @param string $imageString * @return array */ public function getImage($imageString) { $im = imagecreatefromstring($imageString); list($width, $height) = getimagesizefromstring($imageString); $image = array(); for($x = 0;$x < $width;$x++) { for($y =0;$y < $height;$y++) { $rgb = imagecolorat($im, $x, $y); $rgb = imagecolorsforindex($im, $rgb); if($rgb['red'] == 0 && $rgb['green'] == 0 && $rgb['blue'] == 0) { $image[$y][$x] = '*'; } else { $image[$y][$x] = 0; } } } return $image; } /** * 移除无用数据 * @param array $image * @return array */ public function remove($image) { //计算x和y轴的 $xCount = count($image[0]); //60 $yCount = count($image); //30 $xFilter = array(); for($x = 0;$x < $xCount;$x++) { $filter = true; for($y = 0;$y < $yCount;$y++) { $filter = $filter && ($image[$y][$x] == '0'); } if($filter) { $xFilter[] = $x; } } //有字符的列 $xImage = array_values(array_diff(range(0, 59), $xFilter)); //存放关键字 $wordImage = array(); $preX = $xImage[0] - 1; $wordCount = 0; foreach($xImage as $xKey => $x) { if($x != ($preX + 1)) { $wordCount++; } $preX = $x; for($y = 0;$y < $yCount;$y++) { $wordImage[$wordCount][$y][$x] = $image[$y][$x]; } } foreach($wordImage as $key=>$image) { $wordImage[$key] = $this->removeByLine($image); } return $wordImage; } /** * 按行移除无用数据 * @param array $image * @return array */ public function removeByLine($image) { $isFilter = false; foreach($image as $y => $yImage) { if($isFilter == true || array_filter($yImage)) { $isFilter = true; } else { unset($image[$y]); } } krsort($image); $isFilter = false; foreach($image as $y => $yImage) { if($isFilter == true || array_filter($yImage)) { $isFilter = true; } else { unset($image[$y]); } } ksort($image); return $image; } /** * 获取关键字字符串 * @param array $wordImage * @return string */ public function getWordString($wordImage) { $wordString = ''; foreach($wordImage as $image) { foreach($image as $string) { $wordString .= $string; } } return $wordString; } /** * 匹配关键字 * @param array $image * @return array */ public function match($image) { $match = array( 'min' => '', 'key' => '' ); foreach($this->_wordKeys as $k => $v) { $percent = 0.0; similar_text($this->getWordString($image), $v, $percent); if($match['min'] == '') { $match['min'] = $percent; $match['key'] = $k; } else { if($percent > $match['min']) { $match['min'] = $percent; $match['key'] = $k; } } } return $match; } /** * 终端显示验证码 * @param $image */ public function show($image) { foreach($image as $xImage) { foreach($xImage as $yImage) { echo $yImage; } echo PHP_EOL; } echo PHP_EOL; } } $vCode = new vCode(); $codeImage = $vCode->make(); $imageString = $codeImage['image']; $image = $vCode->getImage($imageString); //原图 $vCode->show($image); //去除干扰边框、拆字 $newImage = $vCode->remove($image); $word = array(); $code = ''; foreach($newImage as $image) { $vCode->show($image); $code .= $vCode->match($image)['key']; } echo "生成的验证码为:{$codeImage['code']}" . PHP_EOL; echo "识别的验证码为:{$code}" . PHP_EOL; /* //用来批量生成验证码的特征码。识别他人网站验证码,需要自己采集多张,人肉标记特征码 $vCode = new vCode(); $string = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789'; $max = ceil(strlen($string) / 4); $wordKeys = array(); for($i=0;$i<$max;$i++) { $code = substr($string, $i * 4, 4); $imageString = $vCode->make($code)['image']; $image = $vCode->getImage($imageString); $newImage = $vCode->remove($image); foreach($newImage as $key => $image) { $word = $vCode->getWordString($image); isset($code[$key]) && $wordKeys[$code[$key]] = $word; } } echo var_export($wordKeys); */
登录后复制

运行结果:

7b8866871584234e368769cef033e41.png

以上就是特别简单的PHP验证码识别的详细内容,更多请关注靠谱客其它相关文章!

最后

以上就是娇气鸵鸟最近收集整理的关于特别简单的PHP验证码识别的全部内容,更多相关特别简单内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(92)

评论列表共有 0 条评论

立即
投稿
返回
顶部