博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发生成验证码图片,保证并发也生成不同
阅读量:6071 次
发布时间:2019-06-20

本文共 5447 字,大约阅读时间需要 18 分钟。

hot3.png

/*并发验证码生成,即使并发也不会相同1秒并发100测试通过没有重复没有报错,内存增加40mb左右,增加到80mb后就基本不再增加*/using System;using System.Drawing;using System.Threading.Tasks;using System.Collections.Concurrent;public class CheckCode : System.Web.UI.Page{    protected void Page_Load(object sender, EventArgs e)    {        if (Request["w"] || Request["h"])//重写这里保证输入的都是数字,图片宽高            return;        int imgWidth = int.Parse(Request["w"]);        int imgHeight = int.Parse(Request["h"]);        string tmp = GenerateCheckCode();        Session["checkcode"] = tmp + "|" + DateTime.Now.ToString();        this.CreateCheckCodeImage(tmp, imgWidth, imgHeight);    }    //这段随机验证码生成程序可以另外写,重点是后面的图片生成    private string GenerateCheckCode()    {        int number;        char code;        string checkCode = String.Empty;        System.Random random = new Random(Seed());        for (int i = 0; i < 5; i++)        {        REBUILD:            number = random.Next();            if (number % 2 == 0)                code = (char)('0' + (char)(number % 10));            else                code = (char)('A' + (char)(number % 26));            if (code == '0' || code == 'O')                goto REBUILD;            checkCode += code.ToString();        }        //Response.Cookies.Add(new HttpCookie("CheckCode", checkCode));        return checkCode;    }    //生成图片,并写入验证码    private void CreateCheckCodeImage(string checkCode, int imgW, int imgH)    {        if (string.IsNullOrWhiteSpace(checkCode))            return;        System.Drawing.Bitmap image = new System.Drawing.Bitmap(imgW, imgH);        Graphics g = Graphics.FromImage(image);        object o = new object();        System.IO.MemoryStream ms = new System.IO.MemoryStream();        try        {            int pc = Environment.ProcessorCount;//用并发,知道cpu核心数            // 清空图片背景色            g.Clear(Color.White);            // 画图片的背景噪音线            int parallelCount = pc * 4;//4倍cpu核心数的线条,并发写入            Parallel.ForEach(Partitioner.Create(0, parallelCount, ((int)(parallelCount / pc) + 1)),                range =>                {                    for (int i = range.Item1; i < range.Item2; i++)                    {                        Random random = new Random(Seed());                        int x1 = random.Next(imgW);                        int x2 = random.Next(imgW);                        int y1 = random.Next(imgH);                        int y2 = random.Next(imgH);                        Pen p = new Pen(Color.FromArgb(random.Next()));                        lock (o)                        {                            g.DrawLine(p, x1, y1, x2, y2);                        }                        p.Dispose();                        p = null;                        random = null;                    }                });            //并发画验证码和外边框            Parallel.Invoke(() =>            {                //写验证码                Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));                Color c1 = Color.Blue;                Color c2 = Color.DarkRed;                System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, imgW, imgH), c1, c2, 1.2f, true);                SizeF strSize = new SizeF();                lock (o)                {                    strSize = g.MeasureString(checkCode, font);                }                float left = (imgW - strSize.Width) / 2;                float top = (imgH - strSize.Height) / 2;                lock (o)                {                    g.DrawString(checkCode, font, brush, left, top);                }                //回收                font.Dispose();                font = null;                brush.Dispose();                brush = null;            }, () =>            {                // 画图片的边框线                lock (o)                {                    g.DrawRectangle(new Pen(Color.Silver), 0, 0, imgW - 1, imgH - 1);                }            });            // 画图片的前景噪音点,并发画噪点,16倍cpu核心数的噪点。            parallelCount = pc * 16;            Parallel.ForEach(Partitioner.Create(0, parallelCount, ((int)(parallelCount / pc) + 1)),                range =>                {                    for (int i = range.Item1; i < range.Item2; i++)                    {                        Random random = new Random(Seed());                        int x = random.Next(imgW);                        int y = random.Next(imgH);                        lock (o) { image.SetPixel(x, y, Color.FromArgb(random.Next())); }                        random = null;                    }                });            //写入流            image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);            Response.ClearContent();            Response.ContentType = "image/gif";            Response.BinaryWrite(ms.ToArray());        }        finally        {            //下面全是提示回收的,            g.Dispose();            g = null;            image.Dispose();            image = null;            o = null;            ms.Dispose();            ms = null;            GC.Collect();        }    }    //并发随机种子数生成    public int Seed()    {        byte[] bytes = new byte[4];        System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();        rng.GetBytes(bytes);        return System.Math.Abs(BitConverter.ToInt32(bytes, 0));    }}

转载于:https://my.oschina.net/raddleoj/blog/369636

你可能感兴趣的文章
Linux 获取文件夹下的所有文件
查看>>
对 Sea.js 进行配置(一) seajs.config
查看>>
dom4j解析xml文件
查看>>
第六周
查看>>
斯坦福大学公开课机器学习:梯度下降运算的学习率a(gradient descent in practice 2:learning rate alpha)...
查看>>
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>
sql 字符串操作
查看>>
【转】Android布局优化之ViewStub
查看>>
网络安全管理技术作业-SNMP实验报告
查看>>
根据Uri获取文件的绝对路径
查看>>
Fundebug前端JavaScript插件更新至1.6.0,新增test()方法用于测试
查看>>
Flutter 插件开发:以微信SDK为例
查看>>
.NET[C#]中NullReferenceException(未将对象引用到实例)是什么问题?如何修复处理?...
查看>>
边缘控制平面Ambassador全解读
查看>>
Windows Phone 7 利用计时器DispatcherTimer创建时钟
查看>>
程序员最喜爱的12个Android应用开发框架二(转)
查看>>
vim学习与理解
查看>>
DIRECTSHOW在VS2005中PVOID64问题和配置问题
查看>>