mirror of
https://gitee.com/xiarenalofs/squad-rain-ops-mini.git
synced 2026-08-06 13:26:25 +08:00
92 lines
3.2 KiB
C#
92 lines
3.2 KiB
C#
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($"<svg width=\"{width}\" height=\"{height}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 {width} {height}\">");
|
|
|
|
// Background
|
|
sb.Append($"<rect width=\"100%\" height=\"100%\" fill=\"#f2f2f2\"/>");
|
|
|
|
// 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($"<line x1=\"{x1}\" y1=\"{y1}\" x2=\"{x2}\" y2=\"{y2}\" stroke=\"{color}\" stroke-width=\"1\" opacity=\"0.5\"/>");
|
|
}
|
|
|
|
// 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($"<circle cx=\"{cx}\" cy=\"{cy}\" r=\"1\" fill=\"{color}\" opacity=\"0.5\"/>");
|
|
}
|
|
|
|
// 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($"<text x=\"{x}\" y=\"{y}\" font-family=\"Arial, sans-serif\" font-size=\"{fontSize}\" font-weight=\"bold\" fill=\"{color}\" transform=\"rotate({rotate} {x} {y})\">{code[i]}</text>");
|
|
}
|
|
|
|
sb.Append("</svg>");
|
|
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)})";
|
|
}
|
|
}
|
|
}
|