验证码
2015-04-30 17:28 糯米粥 阅读(606) 评论(0) 编辑 收藏 举报今天项目又用到了验证码。每次都去找,还不是自己项目需要的效果。修改几下后。故备份一下
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Drawing; 6 using System.Web.SessionState; 7 8 namespace MGear.UI.common 9 { 10 /// <summary> 11 /// ValidateCode 的摘要说明 12 /// </summary> 13 public class ValidateCode : IHttpHandler, IRequiresSessionState 14 { 15 16 public void ProcessRequest(HttpContext context) 17 { 18 context.Response.ContentType = "image/jpeg"; 19 20 string code = GetRndStr(); 21 22 // 23 context.Session["code"] = code; 24 25 using (Bitmap img = CreateImages(code, "ch")) 26 { 27 img.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); 28 } 29 //context.Response.Write("Hello World"); 30 } 31 32 public bool IsReusable 33 { 34 get 35 { 36 return false; 37 } 38 } 39 40 /// <summary> 41 /// 数字随机数 42 /// </summary> 43 /// <returns></returns> 44 private string GetRndNum() 45 { 46 string code = string.Empty; 47 Random random = new Random(); 48 for (int i = 0; i < 4; i++) 49 { 50 code += random.Next(9); 51 } 52 return code; 53 } 54 /// <summary> 55 /// 英文随机 56 /// </summary> 57 /// <returns></returns> 58 private string GetRndStr() 59 { 60 string Vchar = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"; 61 string[] VcArray = Vchar.Split(','); 62 string checkCode = string.Empty; 63 Random rand = new Random(); 64 for (int i = 0; i < 4; i++) 65 { 66 int t = rand.Next(VcArray.Length); 67 checkCode += VcArray[t]; 68 } 69 return checkCode; 70 } 71 /// <summary> 72 /// 中文随机 73 /// </summary> 74 /// <returns></returns> 75 private string GetRndCh() 76 { 77 System.Text.Encoding gb = System.Text.Encoding.Default;//获取GB2312编码页(表) 78 object[] bytes = CreateRegionCode(4);//生4个随机中文汉字编码 79 string[] str = new string[4]; 80 System.Text.StringBuilder sb = new System.Text.StringBuilder(); 81 for (int i = 0; i < 4; i++) 82 { 83 //根据汉字编码的字节数组解码出中文汉字 84 str[i] = gb.GetString((byte[])Convert.ChangeType(bytes[i], typeof(byte[]))); 85 sb.Append(str[i].ToString()); 86 } 87 return sb.ToString(); 88 } 89 /// <summary> 90 /// 产生随机中文字符 91 /// </summary> 92 /// <param name="strlength"></param> 93 /// <returns></returns> 94 private static object[] CreateRegionCode(int strlength) 95 { 96 //定义一个字符串数组储存汉字编码的组成元素 97 string[] rBase = new String[16] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; 98 Random rnd = new Random(); 99 object[] bytes = new object[strlength]; 100 101 for (int i = 0; i < strlength; i++) 102 { 103 //区位码第1位 104 int r1 = rnd.Next(11, 14); 105 string str_r1 = rBase[r1].Trim(); 106 //区位码第2位 107 rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i); 108 int r2; 109 if (r1 == 13) 110 { 111 r2 = rnd.Next(0, 7); 112 } 113 else 114 { 115 r2 = rnd.Next(0, 16); 116 } 117 string str_r2 = rBase[r2].Trim(); 118 119 //区位码第3位 120 rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);//更换随机种子 121 int r3 = rnd.Next(10, 16); 122 string str_r3 = rBase[r3].Trim(); 123 124 //区位码第4位 125 rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i); 126 int r4; 127 if (r3 == 10) 128 { 129 r4 = rnd.Next(1, 16); 130 } 131 else if (r3 == 15) 132 { 133 r4 = rnd.Next(0, 15); 134 } 135 else 136 { 137 r4 = rnd.Next(0, 16); 138 } 139 string str_r4 = rBase[r4].Trim(); 140 //定义两个字节变量存储产生的随机汉字区位码 141 byte byte1 = Convert.ToByte(str_r1 + str_r2, 16); 142 byte byte2 = Convert.ToByte(str_r3 + str_r4, 16); 143 144 //将两个字节变量存储在字节数组中 145 byte[] str_r = new byte[] { byte1, byte2 }; 146 147 //将产生的一个汉字的字节数组放入object数组中 148 bytes.SetValue(str_r, i); 149 } 150 return bytes; 151 } 152 /// <summary> 153 /// 画图片的背景图+干扰线 154 /// </summary> 155 /// <param name="checkCode"></param> 156 /// <returns></returns> 157 private Bitmap CreateImages(string checkCode, string type) 158 { 159 int step = 0; 160 if (type == "ch") 161 { 162 step = 5;//中文字符,边界值做大 163 } 164 int iwidth = (int)(checkCode.Length * (30 + step)); 165 System.Drawing.Bitmap image = new System.Drawing.Bitmap(iwidth, 50); 166 Graphics g = Graphics.FromImage(image); 167 g.Clear(Color.White);//清除背景色 168 Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };//定义随机颜色 169 string[] font = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" }; 170 Random rand = new Random(); 171 172 for (int i = 0; i < 50; i++) 173 { 174 int x1 = rand.Next(image.Width); 175 int x2 = rand.Next(image.Width); 176 int y1 = rand.Next(image.Height); 177 int y2 = rand.Next(image.Height); 178 g.DrawLine(new Pen(Color.LightGray, 1), x1, y1, x2, y2);//根据坐标画线 179 } 180 181 for (int i = 0; i < checkCode.Length; i++) 182 { 183 int cindex = rand.Next(7); 184 int findex = rand.Next(5); 185
InstalledFontCollection fc = new InstalledFontCollection(); //这里会得到系统所有的字体
FontFamily ff = fc.Families.Where(d => d.Name.Contains(font[findex])).FirstOrDefault();//判断当前字体是否存在
//可以加载自定义的字体,把字体放在项目中
var path = context.Request.MapPath("/font");
var files = Directory.GetFiles(path);
files.ToList().ForEach(o => { o = Path.GetFileName(o); });
PrivateFontCollection prc = new PrivateFontCollection();
//Request.MapPath(string url)
context.Request.MapPath("/font");
prc.AddFontFile("自定义字体路径");
Font f = new Font(prc.Families[0], 12);
186 Font f = new System.Drawing.Font(font[findex], 30, System.Drawing.FontStyle.Bold); 187 Brush b = new System.Drawing.SolidBrush(c[cindex]); 188 int ii = 4; 189 if ((i + 1) % 2 == 0) 190 { 191 ii = 2; 192 } 193 g.DrawString(checkCode.Substring(i, 1), f, b, 15 + (i * (19 + step)), ii); 194 195 } 196 g.DrawRectangle(new Pen(Color.Black, 0), 0, 0, image.Width - 1, image.Height - 1); 197 System.IO.MemoryStream ms = new System.IO.MemoryStream(); 198 return image; 199 } 200 } 201 }