- 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
- }