验证码生成
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Drawing; 7 using System.Drawing.Drawing2D; 8 using System.IO; 9 using System.Drawing.Imaging; 10 11 namespace Common 12 { 13 public class ValidateCode 14 { 15 //验证码长度 16 private int codeLength; 17 18 //初始化验证码长度 19 public ValidateCode(int codeLength) 20 { 21 this.codeLength = codeLength; 22 } 23 24 //生成验证码字符串 数字+字符串 25 public string CreateValidateCode() 26 { 27 int[] randCode = new int[codeLength]; 28 int[] randNum = new int[codeLength]; 29 string validateStr = ""; 30 31 //获取 得到随机数的随机率有关的数字 32 int seek = (int)DateTime.Now.Ticks;//可能会有问题,因为DateTime.Now.Ticks可能超过int类型 33 34 Random rand = new Random(seek); 35 //获取一个随机数作为随机数的开始 36 int beginRand = rand.Next(0, int.MaxValue - codeLength * 10000); 37 int[] seeks = new int[codeLength]; 38 for (int i = 0; i < codeLength; i++) 39 { 40 beginRand += 10000; 41 seeks[i] = beginRand; 42 } 43 //给每个生成的随机数给不同的随机率 44 for (int j = 0; j < codeLength; j++) 45 { 46 Random r = new Random(seeks[j]); 47 int powNum = (int)Math.Pow(10, codeLength); 48 randNum[j] = r.Next(powNum, int.MaxValue); 49 } 50 //randNum 保存了四个随机数 51 for (int k = 0; k < codeLength; k++) 52 { 53 string numStr = randNum[k].ToString(); 54 int numLen = numStr.Length; 55 Random r = new Random(); 56 int numPostion = r.Next(0, numLen - 1); 57 randCode[k] = int.Parse(numStr.Substring(numPostion, 1)); 58 } 59 for (int i = 0; i < codeLength; i++) 60 { 61 validateStr += randCode[i].ToString(); 62 } 63 return validateStr; 64 } 65 66 67 public byte[] CreateVCodeImg(string validateCode) 68 { 69 //初始化一张图像,点位图 图像的大小:长Math.Ceiling(validateCode.Length * 12.0) 宽:24 px 70 Bitmap bitmap = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), 24); 71 //准备一张画笔 专门为某个图像准备的画笔 72 Graphics g = Graphics.FromImage(bitmap);//Graphics和Bitmap继承了IDisposable接口 所以最好使用后释放 73 try 74 { 75 76 77 Random random = new Random(); 78 79 //用画笔把图像的背景色清空(填充成白色的图像背景) 80 g.Clear(Color.White); 81 82 //画干扰线 循环25次 每次4个数 生成两个点 25条(有可能线被覆盖) 83 //每次循环生成一条线 84 for (int i = 0; i < 25; i++) 85 { 86 int linex1 = random.Next(bitmap.Width); 87 int linex2 = random.Next(bitmap.Width); 88 int liney1 = random.Next(bitmap.Height); 89 int liney2 = random.Next(bitmap.Height); 90 g.DrawLine(new Pen(Color.Silver), linex1, liney1, linex2, liney2); 91 } 92 //准备 93 Font f = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic)); 94 LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, bitmap.Width, bitmap.Height), Color.Blue, Color.DarkRed, 1.2f, true); 95 //把验证码字符串用画笔画到bitmap上 96 g.DrawString(validateCode, f, brush, 3, 2); 97 //生成像素点 验证码图片中的干扰点 会覆盖在文字 画的先后顺序 98 for (int j = 0; j < 100; j++) 99 { 100 int x = random.Next(bitmap.Width); 101 int y = random.Next(bitmap.Height); 102 bitmap.SetPixel(x, y, Color.FromArgb(random.Next())); 103 } 104 //画图片的边框线 边框线在图片的里面 所以边框线不能和bitmap同样大小 105 g.DrawRectangle(new Pen(Color.Silver), 0, 0, bitmap.Width - 1, bitmap.Height - 1); 106 //保存图片 把图片输出要把图片转化成流输出 内存流 107 MemoryStream ms = new MemoryStream(); 108 bitmap.Save(ms, ImageFormat.Jpeg); 109 //输出图片流 110 return ms.ToArray(); 111 } 112 finally 113 { 114 g.Dispose(); 115 bitmap.Dispose(); 116 } 117 } 118 } 119 }