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 }