新开发的安全验证码类,支持生成Gif图片验证码(带噪点,干扰线,网格,随机色背景,随机自定义字体,倾斜,Gif动画)。

上图:

字体及字体文件的路径需要在类中$FontFilePath及$FontFileName中设置。如:

  1. private static $FontFilePath = "static/font/"; //相对地本代码文件的位置
  2. private static $FontFileName = array("3.ttf");// array("1.ttf", "2.ttf", "3.ttf", "4.ttf", "5.ttf", "6.ttf", "7.ttf", "8.ttf"); //

完整代码如下:

  1. <?PHP
  2.  
  3. /**
  4. 说明: 验证码生成类,支持生成Gif图片验证码(带噪点,干扰线,网格,随机色背景,随机自定义字体,倾斜,Gif动画)
  5. 作者: 茶沫
  6. 时间:2013-10-26
  7. 博客:http://www.cnblogs.com/janas
  8.  
  9. 服务端:
  10. $mod = strtolower(isset($_REQUEST["mod"]) ? $_REQUEST["mod"] : "");
  11. if($mod == "code"){
  12. echo SecurityCode::Draw(4, 1, 120, 30, 5, 10, 100, "secode");
  13. die();
  14. }
  15. 调用: <img src="/getcode.php?mod=code" onclick="this.src='/getcode.php?mod=code&r='+Math.round(Math.random(0)*1000)">
  16. 验证:
  17. $reqCode = strtolower(isset($_REQUEST["secode"]) ? $_REQUEST["secode"] : ""); //请求的验证码
  18. $sessionCode = strtolower(isset($_SESSION["secode"]) ? $_SESSION["secode"] : ""); //会话生成的验证码
  19. if($reqCode != $sessionCode){
  20. echo "安全验证码错误!";
  21. die();
  22. }
  23. */
  24. $mod = strtolower(isset($_REQUEST["mod"]) ? $_REQUEST["mod"] : "");
  25. if ($mod == "code") {
  26. echo SecurityCode::Draw(4, 15, 100, 27, 10, 2, 100, "secode");
  27. die();
  28. }
  29.  
  30. //安全验证码类
  31. class SecurityCode {
  32.  
  33. private static $Debug = 0;
  34. private static $Code = '';
  35. private static $Chars = 'bcdefhkmnrstuvwxyABCDEFGHKMNPRSTUVWXY34568';
  36. //private static $Chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890';
  37. private static $TextGap = 20;
  38. private static $TextMargin = 5;
  39. private static $FontFilePath = "static/font/"; //相对地本代码文件的位置
  40. private static $FontFileName =array("3.ttf");// array("1.ttf", "2.ttf", "3.ttf", "4.ttf", "5.ttf", "6.ttf", "7.ttf", "8.ttf"); //
  41. private static $Img = 'GIF89a'; //GIF header 6 bytes
  42. private static $BUF = Array();
  43. private static $LOP = 0;
  44. private static $DIS = 2;
  45. private static $COL = -1;
  46. private static $IMG = -1;
  47.  
  48. /**
  49. 生成GIF图片验证
  50. @param int $L 验证码长度
  51. @param int $F 生成Gif图的帧数
  52. @param int $W 宽度
  53. @param int $H 高度
  54. @param int $MixCnt 干扰线数
  55. @param int $lineGap 网格线间隔
  56. @param int $noisyCnt 澡点数
  57. @param int $sessionName 验证码Session名称
  58. */
  59. public static function Draw($L = 4, $F = 1, $W = 150, $H = 30, $MixCnt = 2, $lineGap = 0, $noisyCnt = 10, $sessionName = "Code") {
  60. ob_start();
  61. ob_clean();
  62.  
  63. for ($i = 0; $i < $L; $i++) {
  64. self::$Code .= SubStr(self::$Chars, mt_rand(0, strlen(self::$Chars) - 1), 1);
  65. }
  66.  
  67. if (!isset($_SESSION))
  68. session_start();
  69. $_SESSION[$sessionName] = strtolower(self::$Code);
  70.  
  71. $bgRGB = array(rand(0, 255), rand(0, 255), rand(0, 255));
  72. //生成一个多帧的GIF动画
  73. for ($i = 0; $i < $F; $i++) {
  74. $img = ImageCreate($W, $H);
  75.  
  76. //背景色
  77. $bgColor = imagecolorallocate($img, $bgRGB[0], $bgRGB[1], $bgRGB[2]);
  78. ImageColorTransparent($img, $bgColor);
  79. unset($bgColor);
  80.  
  81. //添加噪点
  82. $maxNoisy = rand(0, $noisyCnt);
  83. $noisyColor = imagecolorallocate($img, rand(0, 255), rand(0, 255), rand(0, 255));
  84. for ($k = 0; $k <= $maxNoisy; $k++) {
  85. imagesetpixel($img, rand(0, $W), rand(0, $H), $noisyColor);
  86. }
  87.  
  88. //添加网格
  89. if ($lineGap > 0) {
  90. for ($m = 0; $m < ($W / $lineGap); $m++) { //竖线
  91. imageline($img, $m * $lineGap, 0, $m * $lineGap, $H, $noisyColor);
  92. }
  93. for ($n = 0; $n < ($H / $lineGap); $n++) { //横线
  94. imageline($img, 0, $n * $lineGap, $W, $n * $lineGap, $noisyColor);
  95. }
  96. }
  97. unset($noisyColor);
  98.  
  99. // 添加干扰线
  100. for ($k = 0; $k < $MixCnt; $k++) {
  101. $wr = mt_rand(0, $W);
  102. $hr = mt_rand(0, $W);
  103. $lineColor = imagecolorallocate($img, rand(0, 255), rand(0, 255), rand(0, 255));
  104. imagearc($img, $W - floor($wr / 2), floor($hr / 2), $wr, $hr, rand(90, 180), rand(180, 270), $lineColor);
  105. unset($lineColor);
  106. unset($wr, $hr);
  107. }
  108.  
  109. //第一帧忽略文字
  110. if ($i != 0 || $F <= 1) {
  111. //文字
  112. $foreColor = imagecolorallocate($img, rand(0, 255), rand(0, 255), rand(0, 255));
  113. for ($j = 0; $j < $L; $j++) {
  114. $fontFile = self::$FontFilePath . self::$FontFileName[rand(0, count(self::$FontFileName) - 1)];
  115. if (!file_exists($fontFile))
  116. imagestring($img, 4, self::$TextMargin + $j * self::$TextGap, ($H - rand($H / 2, $H)), self::$Code[$j], $foreColor);
  117. else
  118. imageTTFtext($img, rand(15, 18), rand(-15, 15), self::$TextMargin + $j * self::$TextGap, ($H - rand(7, 10)), $foreColor, $fontFile, self::$Code[$j]);
  119. }
  120. unset($foreColor);
  121. }
  122.  
  123. ImageGif($img);
  124. Imagedestroy($img);
  125. $Imdata[] = ob_get_contents();
  126. OB_clean();
  127. }
  128.  
  129. unset($W, $H, $B);
  130. if (self::$Debug) {
  131. echo $_SESSION['code'];
  132. echo '<pre>', Var_Dump($Imdata), '</pre>';
  133. die();
  134. }
  135. header('Content-type:image/gif');
  136. return self::CreateGif($Imdata, 20);
  137. unset($Imdata);
  138. }
  139.  
  140. private static function CreateGif($GIF_src, $GIF_dly = 10, $GIF_lop = 0, $GIF_dis = 0, $GIF_red = 0, $GIF_grn = 0, $GIF_blu = 0, $GIF_mod = 'bin') {
  141. if (!is_array($GIF_src) && !is_array($GIF_tim)) {
  142. throw New Exception('Error:' . __LINE__ . ',Does not supported function for only one image!!');
  143. die();
  144. }
  145. self::$LOP = ($GIF_lop > -1) ? $GIF_lop : 0;
  146. self::$DIS = ($GIF_dis > -1) ? (($GIF_dis < 3) ? $GIF_dis : 3) : 2;
  147. self::$COL = ($GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1) ? ($GIF_red | ($GIF_grn << 8) | ($GIF_blu << 16)) : -1;
  148. for ($i = 0, $src_count = count($GIF_src); $i < $src_count; $i++) {
  149. if (strToLower($GIF_mod) == 'url') {
  150. self::$BUF[] = fread(fopen($GIF_src[$i], 'rb'), filesize($GIF_src[$i]));
  151. } elseif (strToLower($GIF_mod) == 'bin') {
  152. self::$BUF[] = $GIF_src[$i];
  153. } else {
  154. throw New Exception('Error:' . __LINE__ . ',Unintelligible flag (' . $GIF_mod . ')!');
  155. die();
  156. }
  157. if (!(Substr(self::$BUF[$i], 0, 6) == 'GIF87a' Or Substr(self::$BUF[$i], 0, 6) == 'GIF89a')) {
  158. throw New Exception('Error:' . __LINE__ . ',Source ' . $i . ' is not a GIF image!');
  159. die();
  160. }
  161. for ($j = (13 + 3 * (2 << (ord(self::$BUF[$i]{10}) & 0x07))), $k = TRUE; $k; $j++) {
  162. switch (self::$BUF[$i]{$j}) {
  163. case '!':
  164. if ((substr(self::$BUF[$i], ($j + 3), 8)) == 'NETSCAPE') {
  165. throw New Exception('Error:' . __LINE__ . ',Could not make animation from animated GIF source (' . ($i + 1) . ')!');
  166. die();
  167. }
  168. break;
  169. case ';':
  170. $k = FALSE;
  171. break;
  172. }
  173. }
  174. }
  175. self::AddHeader();
  176. for ($i = 0, $count_buf = count(self::$BUF); $i < $count_buf; $i++) {
  177. self::AddFrames($i, $GIF_dly);
  178. }
  179. self::$Img .= ';';
  180. return (self::$Img);
  181. }
  182.  
  183. private static function AddHeader() {
  184. $i = 0;
  185. if (ord(self::$BUF[0]{10}) & 0x80) {
  186. $i = 3 * (2 << (ord(self::$BUF[0]{10}) & 0x07));
  187. self::$Img .= substr(self::$BUF[0], 6, 7);
  188. self::$Img .= substr(self::$BUF[0], 13, $i);
  189. self::$Img .= "!\377\13NETSCAPE2.0\3\1" . chr(self::$LOP & 0xFF) . chr((self::$LOP >> 8) & 0xFF) . "\0";
  190. }
  191. unset($i);
  192. }
  193.  
  194. private static function AddFrames($i, $d) {
  195. $L_str = 13 + 3 * (2 << (ord(self::$BUF[$i]{10}) & 0x07));
  196. $L_end = strlen(self::$BUF[$i]) - $L_str - 1;
  197. $L_tmp = substr(self::$BUF[$i], $L_str, $L_end);
  198. $G_len = 2 << (ord(self::$BUF[0]{10}) & 0x07);
  199. $L_len = 2 << (ord(self::$BUF[$i]{10}) & 0x07);
  200. $G_rgb = substr(self::$BUF[0], 13, 3 * (2 << (ord(self::$BUF[0]{10}) & 0x07)));
  201. $L_rgb = substr(self::$BUF[$i], 13, 3 * (2 << (ord(self::$BUF[$i]{10}) & 0x07)));
  202. $L_ext = "!\xF9\x04" . chr((self::$DIS << 2) + 0) . chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . "\x0\x0";
  203. if (self::$COL > -1 && ord(self::$BUF[$i]{10}) & 0x80) {
  204. for ($j = 0; $j < (2 << (ord(self::$BUF[$i]{10}) & 0x07)); $j++) {
  205. if (ord($L_rgb{3 * $j + 0}) == (self::$COL >> 0) & 0xFF && ord($L_rgb{3 * $j + 1}) == (self::$COL >> 8) & 0xFF && ord($L_rgb{3 * $j + 2}) == (self::$COL >> 16) & 0xFF) {
  206. $L_ext = "!\xF9\x04" . chr((self::$DIS << 2) + 1) . chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . chr($j) . "\x0";
  207. break;
  208. }
  209. }
  210. }
  211. switch ($L_tmp{0}) {
  212. case '!':
  213. $L_img = substr($L_tmp, 8, 10);
  214. $L_tmp = substr($L_tmp, 18, strlen($L_tmp) - 18);
  215. break;
  216. case ',':
  217. $L_img = substr($L_tmp, 0, 10);
  218. $L_tmp = substr($L_tmp, 10, strlen($L_tmp) - 10);
  219. break;
  220. }
  221. if (ord(self::$BUF[$i]{10}) & 0x80 && self::$IMG > -1) {
  222. if ($G_len == $L_len) {
  223. if (self::Compare($G_rgb, $L_rgb, $G_len)) {
  224. self::$Img .= ($L_ext . $L_img . $L_tmp);
  225. } else {
  226. $byte = ord($L_img{9});
  227. $byte |= 0x80;
  228. $byte &= 0xF8;
  229. $byte |= (ord(self::$BUF[0]{10}) & 0x07);
  230. $L_img{9} = chr($byte);
  231. self::$Img .= ($L_ext . $L_img . $L_rgb . $L_tmp);
  232. }
  233. } else {
  234. $byte = ord($L_img{9});
  235. $byte |= 0x80;
  236. $byte &= 0xF8;
  237. $byte |= (ord(self::$BUF[$i]{10}) & 0x07);
  238. $L_img{9} = chr($byte);
  239. self::$Img .= ($L_ext . $L_img . $L_rgb . $L_tmp);
  240. }
  241. } else {
  242. self::$Img .= ($L_ext . $L_img . $L_tmp);
  243. }
  244. self::$IMG = 1;
  245. }
  246.  
  247. private static function Compare($G_Block, $L_Block, $Len) {
  248. for ($i = 0; $i < $Len; $i++) {
  249. if ($G_Block{3 * $i + 0} != $L_Block{3 * $i + 0} || $G_Block{3 * $i + 1} != $L_Block{3 * $i + 1} || $G_Block{3 * $i + 2} != $L_Block{3 * $i + 2}) {
  250. return (0);
  251. }
  252. }
  253. return (1);
  254. }
  255.  
  256. }

Gif图片验证码类的更多相关文章

  1. PHP编写的图片验证码类文件分享方法

    适用于自定义的验证码类! <?php/* * To change this license header, choose License Headers in Project Propertie ...

  2. PHP:现有图片验证码类

    文章来源:http://www.cnblogs.com/hello-tl/p/7593022.html <?php class TL_Captcha_img{ private $image; / ...

  3. 图片验证码的JAVA工具类

    我们平时开发时经常会遇到需要图片验证码,基础的验证码包括了数字.字母.甚至可能有汉字.下面我给出一个简单的工具类. package com..ankang.tony.util; import java ...

  4. 开发工具类API调用的代码示例合集:六位图片验证码生成、四位图片验证码生成、简单验证码识别等

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 六位图片验证码生成:包括纯数字.小写字母.大写字母.大小写混合.数 ...

  5. PHP-解析验证码类--学习笔记

    1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1  定义变量 //随机因子 private $char ...

  6. 字符型图片验证码识别完整过程及Python实现

    字符型图片验证码识别完整过程及Python实现 1   摘要 验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的 防火墙 功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越 ...

  7. android图片验证码--自绘控件

    自绘控件的内容都是自己绘制出来的 大致流程如下: 1.定义一个类继承view 使用TypedArray初始化属性集合 在view的构造方法中 有一个AttributeSet的参数 很明显是用来保存控件 ...

  8. THINKPHP源码学习--------验证码类

    TP3.2验证码类的理解 今天在学习中用到了THINKPHP验证码,为了了解究竟,就开始阅读TP验证码的源码. 源码位置:./ThinkPHP/Library/Think/Verify.class.p ...

  9. ThinkPHP 3.2.3 加减乘法验证码类

    ThinkPHP 3.2.3 自带的验证码类位于 /ThinkPHP/Library/Think/Verify.class.php,字体文件位于 /ThinkPHP/Library/Think/Ver ...

随机推荐

  1. 美国评出2016最值得去的旅游胜地+纯电动车郊游记+DIY一个小电动车

    美国评出2016最值得去的旅游胜地(10) http://bbs.miercn.com/bd/201510/thread_569397_1_10.html 自带发电机! 北汽E150 EV纯电动车郊游 ...

  2. javaEE中的字符编码问题

    0 web.xml中注册的CharacterEncodingFilter <!-- 配置字符集过滤器 --> <filter> <filter-name>encod ...

  3. node第一个程序

    var http = require('http') var url = require('url') var fs=require("fs") var router = requ ...

  4. 微服务与SOA

    微服务跟SOA有什么区别呢,可以把微服务当做去除了ESB的SOA.ESB是SOA架构中的中心总线,拓扑结构应该是星形的,而微服务是去中心化的分布式软件架构. 一.巨石(monolith) web应用程 ...

  5. 做为 Apple Store App 独立开发者,你要搞限时促销,为你的应用生成激活码(或者优惠券),使用 Python 如何生成 200 个激活码(或者优惠券)?

    import random import string def GenKey(length): chars = string.ascii_letters + string.digits return ...

  6. vue脚手架解决跨域问题-------配置反向代理

    1.打开config/index.js 2.在dev配置对象中找到proxyTable:{} 3.添加如下配置 // 配置反向代理,解决跨域请求 proxyTable: { '/api': { tar ...

  7. echo指令

    1.在Linux中echo命令用来在标准输出上显示一段字符,比如:echo "the echo command test!" 这个就会输出“the echo command tes ...

  8. 《React-Native系列》RN与native交互与数据传递

    RN怎么与native交互的呢? 下面我们通过一个简单的Demo来实现:RN页面调起Native页面,Native页面选择电话本数据,将数据回传给RN展示. 首先是 Native侧 1.MainAct ...

  9. Convolutional Neural Network

    Why CNN for Image 图片是由像素点组成的,可以这样来解释深度神经网络对图片的处理. 第一层的layer是最基本的分类器,区分一些基本的特征,比如颜色.是否有斜线. 第二层的layer会 ...

  10. JAVA实现IP地址解析

    转载至:http://blog.csdn.net/dragontang/article/details/4151660 http://www.iteye.com/topic/340548#