CAPTCHA generation and verification
Latest stable Based on Image release 0.3.0
Library module
Problem
Section titled “Problem”This module generates Java2D CAPTCHA images and supplies a one-shot verification contract. It keeps rendering, challenge metadata, answer matching, and storage boundaries explicit so applications can replace the in-memory pieces without replacing the image generator.
When to use it
Section titled “When to use it”Use it for bounded human-verification challenges in JVM services that do not require a native image runtime. Use the Ktor adapter for ready-made HTTP routes. It is not a complete anti-abuse system: durable distributed storage, rate limiting, bot detection, and audit policy remain application concerns.
Coordinates
Section titled “Coordinates”Maven coordinate: io.github.bluetape4k.image:bluetape4k-images-captcha
dependencies { implementation(platform("io.github.bluetape4k:bluetape4k-dependencies:<version>")) implementation("io.github.bluetape4k.image:bluetape4k-images-captcha")}Core concepts
Section titled “Core concepts”CaptchaGenerator renders a CaptchaChallenge. IssuedCaptchaChallenge is the serializable metadata; do not serialize the Scrimage-bearing challenge. CaptchaChallengeStore.consume is the one-shot boundary, and CaptchaVerificationService consumes before comparing to prevent replay.
InMemoryCaptchaChallengeStore is JVM-local and intended for tests, demos, or a single-node process. Production clusters need an atomic distributed consume implementation.
Quick start
Section titled “Quick start”val generator = captchaGenerator { length(6) expiresAfter(5.minutes)}val verifier = CaptchaVerificationService( answerMatcher = CaptchaAnswerMatcher.caseInsensitive(),)
val challenge = generator.generate()val id = CaptchaChallengeId("login-42")verifier.issue(id, challenge)
val result = verifier.verify(id, submittedAnswer)check(result.verified)API by task
Section titled “API by task”- Generate synchronously with
generateor from a coroutine withgenerateSuspend. - Configure dimensions, fonts, colors, noise, distortion, charset, length, and expiry through
CaptchaOptionsBuilder. - Persist only
IssuedCaptchaChallengeplus encoded image bytes. - Implement
CaptchaChallengeStorefor Redis or another atomic shared store. - Select exact or trimmed case-insensitive matching through
CaptchaAnswerMatcher.
Recommended patterns
Section titled “Recommended patterns”Use a cryptographically unpredictable public id and enforce one verification attempt per id. Keep the answer out of logs, client payloads, and metrics. Treat expiry and store TTL as the same policy and apply request-level rate limits outside this library.
Integrations
Section titled “Integrations”bluetape4k-images-ktor exposes issue/verify routes over these contracts. The generated image is an ImmutableImage, so the core image writers can encode it independently of verification metadata.
Configuration
Section titled “Configuration”Defaults are six uppercase characters from ABCDEFGHJKLMNPQRSTUVWXYZ23456789, 200×80 pixels, font size 36, medium noise, no distortion, and five-minute expiry. Length is limited to 1..32; dimensions to 1..2000; font size to 1..512. Text must include a visible color distinct from the background.
Failure modes
Section titled “Failure modes”Verification returns Success, WrongAnswer, Expired, or NotFound. Because verification consumes first, a retry after any result becomes NotFound. Invalid option ranges fail at construction. Java2D rendering errors propagate to the caller.
Operations
Section titled “Operations”Java2D rendering is CPU-bound. generateSuspend honors cancellation before rendering begins, but cancellation is not guaranteed in the middle of the non-suspending draw. Run headless in servers and observe generation latency without recording answers.
Testing
Section titled “Testing”Use Java2dCaptchaGeneratorTest for rendering bounds, CaptchaOptionsTest for validation, and CaptchaVerificationServiceTest for expiry, replay, and matcher behavior. Inject a Clock and deterministic ids in tests.
Workshops and learning path
Section titled “Workshops and learning path”Start with generation and local one-shot verification, then move the store to shared infrastructure, and finally add the Ktor route adapter. Test expiry and duplicate submissions before tuning visual distortion.
Limitations
Section titled “Limitations”The in-memory store is not distributed or durable and performs no background expiry cleanup. The module does not provide throttling, identity binding, accessibility alternatives, or a security guarantee against modern vision models.
Release diagrams
Section titled “Release diagrams”These diagrams are loaded directly from README assets published with the 0.3.0 release and pinned to its immutable commit. They describe this manual’s released structure and runtime flows, not later Snapshot changes. Select a preview to open the SVG at the same release commit.
CAPTCHA challenge preview
Section titled “CAPTCHA challenge preview”Release README: images-captcha/README.md
