using System; using System.Text; using System.Security.Cryptography; namespace RainOpsMini.Helpers { public static class CaptchaHelper { private static readonly char[] Chars = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ".ToCharArray(); public static (string Code, string Svg) GenerateCaptcha(int width = 120, int height = 40) { var code = GenerateRandomCode(4); var svg = GenerateSvg(code, width, height); return (code, svg); } private static string GenerateRandomCode(int length) { var sb = new StringBuilder(length); var data = new byte[length]; using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(data); } foreach (var b in data) { sb.Append(Chars[b % Chars.Length]); } return sb.ToString(); } private static string GenerateSvg(string code, int width, int height) { var sb = new StringBuilder(); var random = new Random(); sb.Append($""); // Background sb.Append($""); // Noise lines for (int i = 0; i < 5; i++) { int x1 = random.Next(0, width); int y1 = random.Next(0, height); int x2 = random.Next(0, width); int y2 = random.Next(0, height); string color = GetRandomColor(random); sb.Append($""); } // Dots for (int i = 0; i < 50; i++) { int cx = random.Next(0, width); int cy = random.Next(0, height); string color = GetRandomColor(random); sb.Append($""); } // Text int charWidth = width / code.Length; for (int i = 0; i < code.Length; i++) { int x = i * charWidth + random.Next(5, 10); int y = height / 2 + random.Next(5, 10); int fontSize = random.Next(20, 28); string color = GetRandomDarkColor(random); int rotate = random.Next(-20, 20); sb.Append($"{code[i]}"); } sb.Append(""); return sb.ToString(); } private static string GetRandomColor(Random random) { return $"rgb({random.Next(0, 256)},{random.Next(0, 256)},{random.Next(0, 256)})"; } private static string GetRandomDarkColor(Random random) { return $"rgb({random.Next(0, 150)},{random.Next(0, 150)},{random.Next(0, 150)})"; } } }