生成验证码
最近站点遇到大流量,翻看日志后发觉有人在恶意注册和登陆。在不能封IP的前提下觉得用验证码来缓解问题。
Code
/// <summary>
/// 输出验证码图片并存储Session
/// </summary>
/// <param name="sessionName"></param>
/// <param name="str"></param>
public static void MakeSpamImageGen(string sessionName, string str)
{
HttpContext context = System.Web.HttpContext.Current;
int charsNo = 5;
int fontSize = 12;
int bgWidth = 60;
int bgHeight = 20;
float x = (bgWidth - (charsNo * (fontSize + 0.5F))) / 2; // TODO: optimize
float y = (bgHeight - (fontSize * 1.7F)) / 2; // TODO: optimize
//设置字体大小以及输出图片大小
if (fontSize == -1) fontSize = 30;
if (bgWidth == -1) bgWidth = 290;
if (bgHeight == -1) bgHeight = 80;
//获取输出内容
string genText = str;
context.Session[sessionName] = genText;
Bitmap raster;
Graphics graphicObj;
string bgFilePath = context.Server.MapPath(context.Request.ApplicationPath + "/Images/AntiSpamBgImgs/bg_" + new Random().Next(5) + ".jpg");
System.Drawing.Image imgObj = System.Drawing.Image.FromFile(bgFilePath);
raster = new Bitmap(imgObj, bgWidth, bgHeight);
graphicObj = Graphics.FromImage(raster);
////画图片的背景噪音线
System.Random random = new Random();
SolidBrush brushObj;
for (int a = 0; a < genText.Length; a++)
{
string fontFamily = crypticFonts[new Random().Next(0, 9)];
Font fontObj = new Font(fontFamily, fontSize, FontStyle.Bold);
brushObj = new SolidBrush(colors[random.Next(0, 7)]);
graphicObj.DrawString(genText.Substring(a, 1), fontObj, brushObj, x + (a * fontSize), y);
graphicObj.Flush();
}
graphicObj.Flush();
graphicObj.Dispose();
//将图片随机正弦扭曲
raster = TwistImage(raster, true, random.Next(2, 4), random.Next(0, 2 * (int)PI));
//设置输出的MIME类型
context.Response.ContentType = "image/gif";
//输出文件流到浏览器中
raster.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
//释放资源
context.Response.Flush();
context.Response.End();
}
//字体集合
private static String[] crypticFonts = { "Arial", "Verdana", "Fixedsys", "宋体", "Haettenschweiler", "Lucida Sans Unicode", "Garamond", "Courier New", "Book Antiqua", "Arial Narrow" };
//颜色集合
private static Color[] colors = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
//正弦起始点
private const double PI = 3.1415926535897932384626433832795;
//正弦扭曲率
private const double PI2 = 6.283185307179586476925286766559;
/// <summary>
/// 正弦曲线Wave扭曲图片
/// </summary>
/// <param name="srcBmp">图片路径</param>
/// <param name="bXDir">如果扭曲则选择为True</param>
/// <param name="nMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
/// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
/// <returns></returns>
private static Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase) {
System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
// 将位图背景填充为白色
System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(destBmp);
graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), 0, 0, destBmp.Width, destBmp.Height);
graph.Dispose();
double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
for (int i = 0; i < destBmp.Width; i++) {
for (int j = 0; j < destBmp.Height; j++) {
double dx = 0;
dx = bXDir ? (PI2 * (double)j) / dBaseAxisLen : (PI2 * (double)i) / dBaseAxisLen;
dx += dPhase;
double dy = Math.Sin(dx);
// 取得当前点的颜色
int nOldX = 0, nOldY = 0;
nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
nOldY = bXDir ? j : j + (int)(dy * dMultValue);
System.Drawing.Color color = srcBmp.GetPixel(i, j);
if (nOldX >= 0 && nOldX < destBmp.Width
&& nOldY >= 0 && nOldY < destBmp.Height) {
destBmp.SetPixel(nOldX, nOldY, color);
}
}
}
return destBmp;
}
/// <summary>
/// 输出验证码图片并存储Session
/// </summary>
/// <param name="sessionName"></param>
/// <param name="str"></param>
public static void MakeSpamImageGen(string sessionName, string str)
{
HttpContext context = System.Web.HttpContext.Current;
int charsNo = 5;
int fontSize = 12;
int bgWidth = 60;
int bgHeight = 20;
float x = (bgWidth - (charsNo * (fontSize + 0.5F))) / 2; // TODO: optimize
float y = (bgHeight - (fontSize * 1.7F)) / 2; // TODO: optimize
//设置字体大小以及输出图片大小
if (fontSize == -1) fontSize = 30;
if (bgWidth == -1) bgWidth = 290;
if (bgHeight == -1) bgHeight = 80;
//获取输出内容
string genText = str;
context.Session[sessionName] = genText;
Bitmap raster;
Graphics graphicObj;
string bgFilePath = context.Server.MapPath(context.Request.ApplicationPath + "/Images/AntiSpamBgImgs/bg_" + new Random().Next(5) + ".jpg");
System.Drawing.Image imgObj = System.Drawing.Image.FromFile(bgFilePath);
raster = new Bitmap(imgObj, bgWidth, bgHeight);
graphicObj = Graphics.FromImage(raster);
////画图片的背景噪音线
System.Random random = new Random();
SolidBrush brushObj;
for (int a = 0; a < genText.Length; a++)
{
string fontFamily = crypticFonts[new Random().Next(0, 9)];
Font fontObj = new Font(fontFamily, fontSize, FontStyle.Bold);
brushObj = new SolidBrush(colors[random.Next(0, 7)]);
graphicObj.DrawString(genText.Substring(a, 1), fontObj, brushObj, x + (a * fontSize), y);
graphicObj.Flush();
}
graphicObj.Flush();
graphicObj.Dispose();
//将图片随机正弦扭曲
raster = TwistImage(raster, true, random.Next(2, 4), random.Next(0, 2 * (int)PI));
//设置输出的MIME类型
context.Response.ContentType = "image/gif";
//输出文件流到浏览器中
raster.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
//释放资源
context.Response.Flush();
context.Response.End();
}
//字体集合
private static String[] crypticFonts = { "Arial", "Verdana", "Fixedsys", "宋体", "Haettenschweiler", "Lucida Sans Unicode", "Garamond", "Courier New", "Book Antiqua", "Arial Narrow" };
//颜色集合
private static Color[] colors = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
//正弦起始点
private const double PI = 3.1415926535897932384626433832795;
//正弦扭曲率
private const double PI2 = 6.283185307179586476925286766559;
/// <summary>
/// 正弦曲线Wave扭曲图片
/// </summary>
/// <param name="srcBmp">图片路径</param>
/// <param name="bXDir">如果扭曲则选择为True</param>
/// <param name="nMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
/// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
/// <returns></returns>
private static Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase) {
System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
// 将位图背景填充为白色
System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(destBmp);
graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), 0, 0, destBmp.Width, destBmp.Height);
graph.Dispose();
double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
for (int i = 0; i < destBmp.Width; i++) {
for (int j = 0; j < destBmp.Height; j++) {
double dx = 0;
dx = bXDir ? (PI2 * (double)j) / dBaseAxisLen : (PI2 * (double)i) / dBaseAxisLen;
dx += dPhase;
double dy = Math.Sin(dx);
// 取得当前点的颜色
int nOldX = 0, nOldY = 0;
nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
nOldY = bXDir ? j : j + (int)(dy * dMultValue);
System.Drawing.Color color = srcBmp.GetPixel(i, j);
if (nOldX >= 0 && nOldX < destBmp.Width
&& nOldY >= 0 && nOldY < destBmp.Height) {
destBmp.SetPixel(nOldX, nOldY, color);
}
}
}
return destBmp;
}