其實實現一個圖片驗證碼並不是什么難的問題,主要講究的時驗證的實現上如何提高程序的識別難度.所以在實現過程參考了一下google的做法,由於數字或字母適當重疊對人自身識別並不成什么問題,但對於計算增加的難度相對來說就比較高些了.如果感覺難度不大可以調整一下程序讓讓字母之間緊靠的近一點,也可適當地加下曲線來讓分析上更難.不過做得太過的話,估計人自己都搞不清楚了:)
驗證碼效果
具體實現代碼
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; namespace Smark.ImageNumber { /// /// Copyright © henryfan 2012 /// Email: henryfan@msn.com /// HomePage: http://www.ikende.com /// CreateTime: 2012/10/23 21:18:29 /// public class Generator { const string VALUE = "123456789"; private static Dictionary mCharImages = new Dictionary(26); private static Image mLine; private static Random mRam = new Random(); public static string GeneratorCode() { string code = ""; for (int i = 0; i < 4; i++) { code += VALUE.Substring(GetRamValue() % VALUE.Length, 1); } return code; } static int GetRamValue() { return mRam.Next(); } public static Image GetImage(string code) { Bitmap tmpImg = new Bitmap(100, 40); using (Graphics e = Graphics.FromImage(tmpImg)) { int offset = 2; e.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60); List items = new List(); foreach (char key in code) { items.Add(GetGeneratorItem(key)); } for (int i = 0; i < items.Count; i++) { if (i > 0) { if ((items[i].Value < 0 && items[i - 1].Value > 0) || (items[i].Value > 0 && items[i - 1].Value > 0) || (items[i].Value < 0 && items[i - 1].Value < 0)) offset += 12; else offset += 18; } using (Image img = items[i].DrawImage()) { if (Math.Abs(items[i].Value) > 20) e.DrawImage(img, offset, 6); else if (Math.Abs(items[i].Value) > 20) e.DrawImage(img, offset, 4); else e.DrawImage(img, offset, 2); } } } return tmpImg; } public static System.Collections.IEnumerable GetKeys { get { return mCharImages.Keys; } } private static GeneratorItem GetGeneratorItem(char key) { GeneratorItem item = new GeneratorItem(); int value = GetRamValue() % 25; if (value < 10) value = 10; if (GetRamValue() % 2 == 0) value = -value; item.Value = value; item.Key = key; return item; } class GeneratorItem { public int Value { get; set; } public char Key { get; set; } public Image DrawImage() { Bitmap tmpImg = new Bitmap(50, 50); using (Graphics e = Graphics.FromImage(tmpImg)) { e.RotateTransform(Value, System.Drawing.Drawing2D.MatrixOrder.Append); e.DrawImage(mCharImages[Key], 0, 0); e.Flush(); } return tmpImg; } } static Generator() { HatchBrush sb = new HatchBrush(HatchStyle.Percent40, Color.Black, Color.Black); foreach (char item in VALUE) { Bitmap bmp = new Bitmap(50, 50); using (Graphics g = Graphics.FromImage(bmp)) { g.DrawString(new string(new char[] { item }), new Font("宋體", 24, FontStyle.Italic), sb, 2, 2); } mCharImages[item]= bmp; } mLine = new Bitmap(60, 4); using (Graphics g = Graphics.FromImage(mLine)) { g.FillRectangle(sb, 0, 0, 60, 3); } } } }