30-5-2009 14:27:28
Lần trước post 1 bài về captcha rồi lần này thêm con nữa cho vui. Con này an toàn cao hơn vì sử dụng nhiều loại hình chống bot regconition.
using System;
using System.Data;
using System.Drawing;
namespace captcha
{
public partial class _Default : System.Web.UI.Page
{
private Bitmap TransformImage(Bitmap bmp, Random rnd)
{
int width = bmp.Width;
int height = bmp.Height;
double distort = rnd.Next(5, 15) * (rnd.Next(10) == 1 ? 1 : -1);
// Copy the image so that we're always using the original for source color
using (Bitmap copy = (Bitmap)bmp.Clone())
{
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
// Adds a simple wave
int newX = (int)(x + (distort * Math.Sin(Math.PI * y / 84.0)));
int newY = (int)(y + (distort * Math.Cos(Math.PI * x / 44.0)));
if (newX < 0 || newX >= width) newX = 0;
if (newY < 0 || newY >= height) newY = 0;
bmp.SetPixel(x, y, copy.GetPixel(newX, newY));
}
}
}
return bmp;
}
private Brush GetBrush(Random rnd)
{
Brush brush = Brushes.Black;
int ir = rnd.Next(9);
switch (ir)
{
case 0:
brush = Brushes.DarkCyan;
break;
case 1:
brush = Brushes.DarkGreen;
break;
case 2:
brush = Brushes.Crimson;
break;
case 3:
brush = Brushes.DarkViolet;
break;
case 4:
brush = Brushes.DarkOliveGreen;
break;
case 5:
brush = Brushes.DarkOrchid;
break;
case 6:
brush = Brushes.DarkTurquoise;
break;
}
return brush;
}
private Font GetFont(Random rnd)
{
float sz = 15 + rnd.Next(4);
Font f = new Font("Arial", sz);
int i = rnd.Next(4);
switch(i)
{
case 0: f = new Font("Tahoma", sz, FontStyle.Bold);break;
case 1: f = new Font("Verdana", sz, FontStyle.Bold); break;
case 2: f = new Font("Times New Roman", sz, FontStyle.Bold); break;
}
return f;
}
private void Drawing(Graphics gr, string s, PointF p, Random rnd)
{
float x = p.X;
float y = p.Y;
char[] c = s.ToCharArray();
for (int i = 0; i < c.Length; i++)
{
string ch = c[ i ].ToString();
Brush brush = GetBrush(rnd);
Font font = GetFont(rnd);
SizeF sf = gr.MeasureString(ch, font);
gr.DrawString(ch, font, brush, new PointF(x, y + (rnd.Next(7) - 3)));
x = x + sf.Width / 2;
}
}
private Pen GetPen(Random rnd)
{
Pen p = Pens.Black;
int i = rnd.Next(4);
switch (i)
{
case 0: p = Pens.Crimson; break;
case 1: p = Pens.DarkCyan; break;
case 2: p = Pens.DarkOliveGreen; break;
}
return p;
}
protected void Page_Load(object sender, EventArgs e)
{
Random rnd = new Random();
string captcha = Guid.NewGuid().ToString("N").Substring(0, 5);
Session["CAPTCHA"] = captcha;
int wid = 100;
int hei = 40;
PointF p = new PointF(10 + rnd.Next(14), 4 + rnd.Next(2));
Bitmap bmp = new Bitmap(wid, hei);
Graphics gr = Graphics.FromImage(bmp);
System.Drawing.Rectangle rec = new Rectangle(0, 0, wid, hei);
gr.FillRectangle(Brushes.White, rec);
Drawing(gr, captcha, p, rnd);
//bmp = TransformImage(bmp, rnd);
int max = rnd.Next(2);
for (int i = 0; i < 2 + max; i++)
{
Pen pen = GetPen(rnd);
Point p1 = new Point(rnd.Next(wid), rnd.Next(hei));
Point p2 = new Point(rnd.Next(wid), rnd.Next(hei));
gr.DrawLine(pen, p1, p2);
}
Response.ContentType = "image/jpeg";
Response.Clear();
bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose();
Response.Flush();
Response.End();
}
}
}