.NET培训
美国上市.NET培训机构

400-111-8989

热门课程

.NET点选验证码实现思路分享

  • 时间:2017-02-04
  • 发布:.Net培训
  • 来源:NET知识

先上效果图

【.NET点选验证码实现思路】

如果你被这个效果吸引了就请继续看下去。

贴代码前先说点思路:

1.要有一个汉字库,并按字形分类。(我在数据库里是安部首分类的)

2.获取验证码(也就是取几个文字做验证码)

3.根据取出来的文字去找形近字

4.排列验证码文字和形近字

5.绘制图片

6.显示

7.写个博客分享一下(分享代码改变世界)

一、获取字库

我国文化博大精深,辣么多的字从哪儿来?当然我不可能手动加进去,于是我就在网上随便找了一个能查汉字的网站,去抓别人的数据。抓数据的方法请点传送门。传送门里说的只是思路,如果有不明白的请艾特我。我会在下面共享我的字库。

二、获取验证码

这个就比较简单了这里我就直接贴代码了,下面的代码就是随机排序后取4条数据,我这样写是为了图方便。个人觉得先随机生成ID,然后直接根据ID取数据,这样查询速度会比下面这种写法快。(注意我用的数据库是MySql)

///

/// 获取验证码

///

public List GetCodeText()

{

const string sql = "SELECT * FROM wenzhi ORDER BY RAND() LIMIT 4";

var dataReader = dbHelper.GetDataReader(sql);

var list = DataReaderToList(dataReader);

dataReader.Close();

return list;

}

三、根据取出来的文字去找形近字

因为第一步的时候我存部首了,所以这里我直接根据部首取获取当前部首的形近字。

///

/// 获取答案备选

///

/// 部首编码

/// 当前文字ID

/// 数量

///

public List GetAnswer(string buShouCode, int id,int number=1)

{

string sql = $"SELECT * FROM wenzhi where BuShouCode='{buShouCode}' and ID <> {id} ORDER BY RAND() LIMIT "+ number;

var dataReader = dbHelper.GetDataReader(sql);

var list = DataReaderToList(dataReader);

dataReader.Close();

return list;

}

四.排列验证码文字和形近字

下面的代码是先把备选答案和验证码放在一个集合里然后再对集合排序

public Model.Code GetCode()

{

var wenzlist = _wenZhiDal.GetCodeText(); //获取验证码

var listAnsuwr = new List();//实例化备选答案对象

var answerCode = string.Empty;//答案

var result = new Model.Code

{

Id = Guid.NewGuid().ToString()

};

//根据验证码获取备选答案并把添加到答案添加到备选答案集合

foreach (var item in wenzlist)

{

answerCode += item.ID + ",";

result.AnswerValue += item.Text;

var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID);

listAnsuwr.Add(new Answer { Id = item.ID.ToString(), Img = GetImage(item.Text) });

listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) }));

}

//如果答案个数不够就再去取几个

if (listAnsuwr.Count < 9)

{

var ran = new Random();

var randKey = ran.Next(0, 4);

var item = wenzlist[randKey];

var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID, 9 - listAnsuwr.Count);

listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) }));

}

result.CodeImg = GetImage(result.AnswerValue);//获取图片

result.AnswerValue = answerCode.TrimEnd(',');

result.Answer = RandomSortList(listAnsuwr);//打乱正确答案与形近字的顺序

return result;

}

这是对集合排序的代码

///

/// 随机排列集合

///

///

///

///

private static List RandomSortList(IEnumerable listT)

{

var random = new Random();

var newList = new List();

foreach (var item in listT)

{

newList.Insert(random.Next(newList.Count + 1), item);

}

return newList;

}

五、绘制图片

下面是画图的代码,验证码和备选答案对应两种不同的画法(里面注释写的还算清楚)。不要担心文字旋转x°后人类分不出来,哈哈。代码最后一句我把图片转成了Base64,方便前端调用。

private static string GetImage(string text)

{

Image image;

switch (text.Length)

{

case 1:

image = new Bitmap(50, 40);

break;

case 4:

image = new Bitmap(120, 40);

break;

default:

image = new Bitmap(50, 40);

break;

}

Brush brushText = new SolidBrush(Color.FromArgb(255, 0, 0, 0));

var graphics = Graphics.FromImage(image);

graphics.SmoothingMode = SmoothingMode.AntiAlias;

graphics.Clear(Color.White);

var font = new Font(new FontFamily("华文彩云"), 20, FontStyle.Regular);

if (text.Length > 1)//画验证码

{

//先来两条直线做干扰 然后再画文字

graphics.DrawLine(new Pen(brushText, new Random().Next(1, 3)), new Point(new Random().Next(0, 10), new Random().Next(10, 40)), new Point(new Random().Next(100, 120), new Random().Next(10, 30)));

graphics.DrawLine(new Pen(brushText, new Random().Next(1, 3)), new Point(new Random().Next(20, 50), new Random().Next(0, 10)), new Point(new Random().Next(100, 120), new Random().Next(30, 40)));

graphics.DrawString(text, font, brushText, 0, 10);

}

else//画备选答案

{

Point middle = new Point(25, 20);

graphics.TranslateTransform(middle.X, middle.Y);

//这里是360°随机旋转

graphics.RotateTransform(new Random().Next(0, 360));

var format = new StringFormat(StringFormatFlags.NoClip)

{

Alignment = StringAlignment.Center,

LineAlignment = StringAlignment.Center

};

graphics.DrawString(text, font, brushText, 0, 0, format);

}

brushText.Dispose();

graphics.Dispose();

return ImageToBase64(image);

}

六、显示

直接调用GetCode方法就能返回验证码对象

下面是后台代码,应为正确答案是放在AnswerValue里的所以我先把取出来放Session里面,然后把值清空后再通过json返回给浏览器。

public string GetVerCode()

{

var code = new VerificationCode.Code().GetCode();

Session["VERCODE"] = code.AnswerValue;

code.AnswerValue = "";

return JsonConvert.SerializeObject(code);

}

现在来堆点html代码

<div class="form-group">

                    <ul class="vercode">

                        <li><img src=''/></li>

                        <li><img src=''/></li>

                        <li><img src=''/></li>

                        <li><img src=''/></li>

                        <li class="delete" onclick="delete_input()"></li>

                    </ul>

<div>

<img id="code-image"/> <a href="javascript:void(0);" onclick="load_vercode()">看不清?</a>

                    </div>

                    <ul class="vercode-anwser">

                        <li><img /></li>

                        <li><img /></li>

                        <li><img /></li>

                        <li><img /></li>

                        <li><img /></li>

                        <li><img /></li>

                        <li><img /></li>

                        <li><img /></li>

                        <li><img /></li>

                </ul>

</div>

再来点js代码,这里只实现的图片上的效果,还没对数据验证(这里说说验证思路:每个图片对应一个ID,取到选择图片的ID用逗号分隔,然后与Session里的值对比)

到这里代码就差不多了,以上思路只是单纯的个人想法,有兴趣的朋友一起来吧

.net培训机构转载自网络如有侵权请联系我们

上一篇:.NET Framework 4.6.2改进了WPF和安全性
下一篇:棒!使用.NET Core构建3D游戏引擎

.Net Core 之 MSBuild 介绍

.NET点选验证码实现思路分享

.NET Core 与 .NET Framework的关系介绍

选择城市和中心
贵州省

广西省

海南省