public class MathCaptcha
{
public static MathCaptcha Generate(int degree = 3)
{
if (degree < 2) degree = 2;
var verifier = new MathCaptcha();
var rdm = new Random(unchecked((int)DateTime.Now.Ticks));
var nums = new decimal[] {
rdm.Next(1, (int)Math.Pow(10, degree)),
rdm.Next(1, (int)Math.Pow(10, degree)),
rdm.Next(1, (int)Math.Pow(10, degree))
};
nums = nums.OrderBy(n => n).ToArray();
while (true)
{
if ((decimal)Math.Pow(10, degree) - 1 <= nums[0] * nums[1])
{
nums[2] = Math.Ceiling(nums[2] * (decimal)rdm.NextDouble());
}
else if ((decimal)Math.Pow(10, degree - 1) >= nums[0] * nums[1])
{
nums[0] = Math.Ceiling(nums[0] * (decimal)(rdm.NextDouble() + 1));
}
else
{
break;
}
nums = nums.OrderBy(n => n).ToArray();
}
if (rdm.NextDouble() > 0.5)
{
while (degree != Math.Abs(nums[0] * nums[1] + nums[2]).ToString().Length)
{
nums[2] = Math.Ceiling(nums[2] * (decimal)rdm.NextDouble());
}
if (rdm.NextDouble() > 0.7)
{
verifier.Text = string.Format("{0}x{1}+{2}", nums[0], nums[1], nums[2]);
verifier.Answer = nums[0] * nums[1] + nums[2];
}
else
{
verifier.Text = string.Format("{2}+{0}x{1}", nums[0], nums[1], nums[2]);
verifier.Answer = nums[2] + nums[0] * nums[1];
}
}
else
{
while (degree != Math.Abs(nums[0] * nums[1] - nums[2]).ToString().Length)
{
nums[2] = Math.Ceiling(nums[2] * (decimal)rdm.NextDouble());
}
if (nums[0] * nums[1] - nums[2] > 0)
{
verifier.Text = string.Format("{0}x{1}-{2}", nums[0], nums[1], nums[2]);
verifier.Answer = nums[0] * nums[1] - nums[2];
}
else
{
verifier.Text = string.Format("{2}-{0}x{1}", nums[0], nums[1], nums[2]);
verifier.Answer = nums[2] - nums[0] * nums[1];
}
}
return verifier;
}
public string Text { get; private set; }
public decimal Answer { get; private set; }
private MathCaptcha() { }
public byte[] GetImageData(System.Drawing.Imaging.ImageFormat format)
{
var ms = new System.IO.MemoryStream();
CaptchaImage.Save(ms, format);
ms.Close();
return ms.ToArray();
}
public Bitmap CaptchaImage
{
get
{
var w = Text.Length * 13;
var h = 25;
var rdm = new Random();
var bmp = new Bitmap(w, h);
var graphic = Graphics.FromImage(bmp);
var font = new Font("Verdana", 14, FontStyle.Italic);
for (int i = 1; i <= 10; i++)
{
graphic.DrawLine(GetPen(i), rdm.Next(w), 0, rdm.Next(w), h);
}
graphic.DrawString(Text, font, Brushes.Black, 0, 0);
for (int i = 0; i <= 50; i++)
{
int RandPixelX = rdm.Next(0, w);
int RandPixelY = rdm.Next(0, h);
bmp.SetPixel(RandPixelX, RandPixelY, Color.Blue);
}
return bmp;
}
}
#region Get brush color
protected Pen GetPen(int i)
{
Pen PenLine = new Pen(Brushes.Red, 1);
switch (i)
{
case 1:
PenLine = new Pen(Brushes.Red, 1);
break;
case 2:
PenLine = new Pen(Brushes.BlueViolet, 1);
break;
case 3:
PenLine = new Pen(Brushes.GreenYellow, 1);
break;
case 4:
PenLine = new Pen(Brushes.Gold, 1);
break;
case 5:
PenLine = new Pen(Brushes.MediumBlue, 1);
break;
case 6:
PenLine = new Pen(Brushes.MintCream, 1);
break;
case 7:
PenLine = new Pen(Brushes.Pink, 1);
break;
case 8:
PenLine = new Pen(Brushes.Purple, 1);
break;
case 9:
PenLine = new Pen(Brushes.HotPink, 1);
break;
case 10:
PenLine = new Pen(Brushes.Chocolate, 1);
break;
}
return PenLine;
}
#endregion
}