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