ComnetCaptcha 1.0.0
dotnet add package ComnetCaptcha --version 1.0.0
NuGet\Install-Package ComnetCaptcha -Version 1.0.0
<PackageReference Include="ComnetCaptcha" Version="1.0.0" />
<PackageVersion Include="ComnetCaptcha" Version="1.0.0" />
<PackageReference Include="ComnetCaptcha" />
paket add ComnetCaptcha --version 1.0.0
#r "nuget: ComnetCaptcha, 1.0.0"
#:package ComnetCaptcha@1.0.0
#addin nuget:?package=ComnetCaptcha&version=1.0.0
#tool nuget:?package=ComnetCaptcha&version=1.0.0
ComnetSolution.Captcha
A lightweight, cross-platform CAPTCHA image generator for .NET built on SkiaSharp.
Works on Linux Docker and Windows without any system font installation — the font is embedded in the package.
Features
- ✅ Cross-platform: Linux, Windows, macOS, Docker
- ✅ Embedded font — no system fonts required
- ✅ Ripple/wave distortion effect
- ✅ Randomised noise lines
- ✅ Fully configurable character set, image size, and code length
- ✅ Built-in
Validate()helper (case-insensitive by default) - ✅ ASP.NET Core DI extension (
AddCaptcha) - ✅ Returns Base64 / data URI helpers on the result object
- ✅ Targets .NET 10
Installation
dotnet add package ComnetSolution.Captcha
Or via the NuGet Package Manager:
Install-Package ComnetSolution.Captcha
Quick Start
Minimal (no DI)
using ComnetCaptcha;
// Generate with defaults (120×36 px, 4 chars)
CaptchaResult result = CaptchaGenerator.Generate();
// Send the PNG bytes to the client
return File(result.CaptchaByteData, "image/png");
In HTML as a data URI
CaptchaResult result = CaptchaGenerator.Generate();
string imgSrc = result.ToDataUri(); // "data:image/png;base64,..."
<img src="@imgSrc" alt="CAPTCHA" />
Validate user input
string stored = HttpContext.Session.GetString("captcha") ?? "";
string input = Request.Form["captcha"];
bool valid = CaptchaGenerator.Validate(captchaToken, input); // case-insensitive
ASP.NET Core Integration
Program.cs / Startup
builder.Services.AddCaptcha(options =>
{
options.Width = 160;
options.Height = 48;
options.CodeLength = 6;
options.NoiseLineCount = 3;
options.RippleWave = 4;
options.Letters = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
options.ValidityMinutes = 5;
options.EncryptionIV = "ComnetCaptchaEncryptionIV";
options.EncryptionKey = "ComnetCaptchaEncryptionKey";
options.CaseSensitive = false;
});
Controller
[ApiController]
[Route("api/[controller]")]
public class CaptchaController : ControllerBase
{
private readonly CaptchaOptions _options;
public CaptchaController(CaptchaOptions options)
=> _options = options;
[HttpGet("image")]
public IActionResult GetImage()
{
var result = CaptchaGenerator.Generate(_options);
HttpContext.Session.SetString("captcha_code", result.CaptchaCode);
return File(result.CaptchaByteData, "image/png");
}
[HttpPost("verify")]
public IActionResult Verify([FromForm] string userInput)
{
var stored = HttpContext.Session.GetString("captcha_code") ?? "";
return Ok(new { valid = CaptchaGenerator.Validate(stored, userInput) });
}
}
Minimal API (here no session, so handle via token, pass token and image data to client, then validate with token on submit)
app.MapGet("/captcha", (CaptchaOptions opts, ISession session) =>
{
var result = CaptchaGenerator.Generate(opts);
return new {Img=result.ToDataUri(), Token=result.CaptchaToken};
});
For validate:
app.MapPost("/captcha/verify", (string token, string userInput) =>
{
return new { valid = CaptchaGenerator.Validate(token, userInput) };
});
Configuration Reference
All options can be set via CaptchaOptions:
| Property | Type | Default | Description |
|---|---|---|---|
Letters |
string |
"ABCDEFGHJKMNPQRSTUVWXYZ23456789" |
Character pool (ambiguous chars excluded) |
CodeLength |
int |
4 |
Number of characters in the code |
Width |
int |
120 |
Image width in pixels |
Height |
int |
36 |
Image height in pixels |
NoiseLineCount |
int |
2 |
Number of random noise lines |
RippleWave |
short |
3 |
Wave distortion intensity (0 = disabled) |
CaseSensitive |
bool |
false |
Whether Validate() is case-sensitive |
ValidityMinutes |
int |
5 |
Recommended expiry time for generated codes |
EncryptionKey |
string |
null |
Optional key for encrypting |
EncryptionIV |
string |
null |
Optional IV for encrypting |
CaptchaResult Properties
| Member | Type | Description |
|---|---|---|
CaptchaCode |
string |
The plaintext code to store server-side |
CaptchaByteData |
byte[] |
Raw PNG image bytes |
Timestamp |
DateTime |
UTC time of generation (for expiry logic) |
ToBase64Image() |
string |
Base64-encoded PNG string |
ToDataUri() |
string |
data:image/png;base64,... URI |
CaptchaToken |
string |
Encrypted token containing code and timestamp (if encryption options set) |
Font Note
The package ships with an embedded TTF font so it works out-of-the-box on Linux Docker containers where Arial (or other common fonts) may not be installed.
If you build from source, place a .ttf file at:
src/ComnetCaptcha/Fonts/Arial.ttf
For redistribution-safe font alternatives consider:
- Liberation Sans (Apache 2.0 — metrically compatible with Arial)
- Noto Sans (OFL)
Docker / Linux
No extra steps needed. The NuGet package includes SkiaSharp.NativeAssets.Linux.NoDependencies, so you don't need to install libfontconfig or other native libraries in your Dockerfile.
FROM mcr.microsoft.com/dotnet/aspnet:10.0
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "YourApp.dll"]
Building & Running Tests
git clone https://github.com/yourusername/ComnetCaptcha
cd ComnetCaptcha
# Place a TTF font at:
# src/ComnetCaptcha/Fonts/Arial.ttf
dotnet build
dotnet test
License
MIT © 2026 Comnet Solutions Pte. Lte.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.6)
- SkiaSharp (>= 3.119.2)
- SkiaSharp.NativeAssets.Linux.NoDependencies (>= 3.119.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 108 | 4/15/2026 |
Initial release — cross-platform CAPTCHA generator with SkiaSharp, embedded Arial font, ripple effect, and configurable character sets.