Skip to content

Selection CAPTCHAs

Sepehr0Day edited this page Jun 13, 2026 · 2 revisions

Selection CAPTCHAs

ClickPointCaptcha

The client clicks a point; the server compares it with the hidden target coordinate.

from CaptchaGenerator import CaptchaConfig, ClickPointCaptcha

result = ClickPointCaptcha(
    CaptchaConfig(width=720, height=420, random_seed=42)
).generate(
    name_export="click_point",
    path_export="./output",
    target="circle",
)

print("Show image:", result.path)
print("Instruction:", result.prompt)

# Coordinates received from the user's click.
user_x, user_y = 340, 180
target_x, target_y = result.answer
tolerance = result.metadata["tolerance"]

distance_squared = (user_x - target_x) ** 2 + (user_y - target_y) ** 2
solved = distance_squared <= tolerance ** 2
print("Solved:", solved)

Keep the target coordinate and tolerance on the server.

OddOneOutCaptcha

The user selects the different item in a shape grid.

from CaptchaGenerator import CaptchaConfig, OddOneOutCaptcha

result = OddOneOutCaptcha(
    CaptchaConfig(width=720, height=420, random_seed=42)
).generate(
    name_export="odd_one_out",
    path_export="./output",
    difficulty="hard",
)

print("Show image:", result.path)
print("Rows:", result.metadata["rows"])
print("Columns:", result.metadata["columns"])

# Convert a clicked row and column to a zero-based index.
clicked_row = 2
clicked_column = 1
columns = result.metadata["columns"]
selected_index = clicked_row * columns + clicked_column

solved = selected_index == result.answer
print("Solved:", solved)

When reproducing the Tkinter UI, use the same grid_positions centers as the generator instead of dividing the full image into equal rectangles.

ShapeCountCaptcha

The user counts a requested shape.

from CaptchaGenerator import CaptchaConfig, ShapeCountCaptcha

result = ShapeCountCaptcha(
    CaptchaConfig(width=720, height=420, random_seed=42)
).generate(
    name_export="shape_count",
    path_export="./output",
    fonts=[],
    difficulty="hard",
)

print("Show image:", result.path)
print("Question:", result.prompt)

user_count = "5"
try:
    solved = int(user_count) == result.answer
except ValueError:
    solved = False

print("Solved:", solved)

metadata["target"] and metadata["total_shapes"] are useful for trusted logging but should not be returned blindly to clients.

ColorChallengeCaptcha

The answer is the text's ink color, not the written color name.

from CaptchaGenerator import CaptchaConfig, ColorChallengeCaptcha

result = ColorChallengeCaptcha(
    CaptchaConfig(width=720, height=300, random_seed=42)
).generate(
    name_export="color_challenge",
    path_export="./output",
    fonts=[],
)

print("Show image:", result.path)
print("Question:", result.prompt)

user_color = "blue"
solved = user_color.strip().casefold() == str(result.answer).casefold()
print("Solved:", solved)

The private metadata contains both the displayed word and ink color.

Clone this wiki locally