|
@@ -0,0 +1,123 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Drawing;
|
|
|
+using System.Drawing.Imaging;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+
|
|
|
+namespace CapchaLibrary
|
|
|
+{
|
|
|
+ public class CapchaGenerator
|
|
|
+ {
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Базовый конструктор, создающий генератор капчи по умолчанию
|
|
|
+ /// </summary>
|
|
|
+ public CapchaGenerator()
|
|
|
+ {
|
|
|
+ ValidCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
|
+ SymbolsCount = 6;
|
|
|
+ NoiseCount = 25;
|
|
|
+ random = new Random(DateTime.Now.Microsecond);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Конструктор генератора, позволяющий задавать используемые при создании капчи символы, количество символов в капче и количество шума
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="validCharacters">Используемые при создании символы</param>
|
|
|
+ /// <param name="symbolsCount">Количество символов в капче</param>
|
|
|
+ public CapchaGenerator(string validCharacters, int symbolsCount, int noiseCount)
|
|
|
+ {
|
|
|
+ ValidCharacters = validCharacters;
|
|
|
+ SymbolsCount = symbolsCount;
|
|
|
+ NoiseCount = noiseCount;
|
|
|
+ random = new Random(DateTime.Now.Microsecond);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Строка состоящая из символов, использующихся при создании капчи
|
|
|
+ /// </summary>
|
|
|
+ public string ValidCharacters { get; init; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Количество символов в капче
|
|
|
+ /// </summary>
|
|
|
+ public int SymbolsCount { get; init; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Количество шума на капче
|
|
|
+ /// </summary>
|
|
|
+ public int NoiseCount { get; init; }
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Метод генерации капчи
|
|
|
+ /// </summary>
|
|
|
+ /// <returns>Данные по сгенерированной капче</returns>
|
|
|
+ public CapchaData GenerateCapcha()
|
|
|
+ {
|
|
|
+ string capchaCode = GenerateCapchaCode();
|
|
|
+ Bitmap capcha = GenerateCapcha(capchaCode);
|
|
|
+ return new CapchaData(capcha, capchaCode);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private readonly Dictionary<int,(Color, Brush)> CapchaColors = new Dictionary<int,(Color, Brush)>()
|
|
|
+ {
|
|
|
+ { 0, (Color.Aquamarine, Brushes.Aqua) },
|
|
|
+ { 1, (Color.PapayaWhip, Brushes.Pink) },
|
|
|
+ { 2, (Color.Coral, Brushes.IndianRed) },
|
|
|
+ };
|
|
|
+
|
|
|
+ private readonly Random random;
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Метод генерации кода капчи
|
|
|
+ /// </summary>
|
|
|
+ /// <returns>Код капчи</returns>
|
|
|
+ private string GenerateCapchaCode() =>
|
|
|
+ new string(Enumerable.Repeat(ValidCharacters, SymbolsCount)
|
|
|
+ .Select(s => s[random.Next(s.Length)])
|
|
|
+ .ToArray());
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Метод генерации изображения капчи
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="capchaCode">Код капчи</param>
|
|
|
+ /// <returns>Изображение капчи</returns>
|
|
|
+ private Bitmap GenerateCapcha(string capchaCode)
|
|
|
+ {
|
|
|
+ Bitmap capcha = new(2560, 1440);
|
|
|
+ (Color, Brush) colors = GetRandomCapchaColor();
|
|
|
+ using (Graphics graphics = Graphics.FromImage(capcha))
|
|
|
+ {
|
|
|
+ graphics.Clear(colors.Item1);
|
|
|
+ int SymbolX = 150;
|
|
|
+ int SymbolY = 650;
|
|
|
+ foreach (char symbol in capchaCode)
|
|
|
+ {
|
|
|
+ int NextSymbolY = SymbolY + (random.Next(0, 600) - 600);
|
|
|
+ graphics.DrawString(symbol.ToString(), new Font("Comic Sans MS", 320, FontStyle.Bold), colors.Item2, new PointF(SymbolX, NextSymbolY));
|
|
|
+ SymbolX += 360;
|
|
|
+ }
|
|
|
+ for(int noiseCounter = 0; noiseCounter < NoiseCount; noiseCounter++)
|
|
|
+ {
|
|
|
+ graphics.DrawLine(new Pen(Brushes.DarkBlue, 5)
|
|
|
+ , new Point(random.Next(0, 2560), random.Next(0, 1440))
|
|
|
+ , new Point(random.Next(0, 2560), random.Next(0, 1440)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return capcha;
|
|
|
+ }
|
|
|
+
|
|
|
+ private (Color, Brush) GetRandomCapchaColor()
|
|
|
+ {
|
|
|
+ (Color, Brush) brush;
|
|
|
+ CapchaColors.TryGetValue(random.Next(0,3), out brush);
|
|
|
+ return brush;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|