Captcha
Picture captchas made on your own server: distorted letters as a PNG data URL and the answer to keep in the session.
Version 1.0.0 · 2 functions · 1 crate
Functions
What use captcha.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use captcha_new, captcha_check from captcha (Quillo 0.6).
captcha_new(length: int, hard: bool) → mapor an errorA new captcha of length characters (4 to 8): { image, answer }. image is a data:image/png;base64,... URL for an <img src>, 220 by 110 pixels; keep answer on the server (in the session), never in the page. hard adds more noise and waves.
captcha_check(answer: str, typed: str) → boolWhether what the visitor typed is the answer: spaces around it ignored, and capitals too, since some letters look alike in both. An empty answer on either side is false.
Get it
$ quillo install captcha # captcha.qwer into this folder$ quillo install captcha --example # and its example, captcha.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/captcha.qwer$ curl -O https://quillolang.org/plugins/files/captcha.qweThen, in your program, all of it or only what you call:
use captcha.qweruse captcha_new, captcha_check from captcha // Quillo 0.6: only theseIt uses this crate, which cargo fetches the first time the plugin is built:
captcha = "0.0.9"Example
// A contact form with a picture captcha; the answer stays in the session.//// quillo run captcha.qwe then open http://localhost:8080/contactuse "captcha.qwer"route GET /contact { let c = captcha_new(5, false)? set_session({ captcha: c.answer }, { max_age: "10m" }) <form method="post" action="/contact"> <img src={c.image} alt="The letters to type"/> <input name="answer" autocomplete="off" placeholder="The letters above"/> <textarea name="message"></textarea> <button>Send</button> </form>}route POST /contact { form: { answer: str, message: str } } { if !captcha_check(session().captcha ?? "", answer) { reply 400 "The letters did not match: try a new picture." } set_session({}) { sent: message }}route GET /check { let c = captcha_new(6, true)? { length: len(c.answer), png: starts_with(c.image, "data:image/png;base64,"), right: captcha_check(c.answer, upper(c.answer)), wrong: captcha_check(c.answer, "nope") }}$ quillo run captcha.qwe$ curl 'localhost:8080/contact'$ curl 'localhost:8080/check'Source
//! Picture captchas made on your own server: distorted letters as a PNG data URL and the answer, for sign-up and contact forms without a third party.//! version: 1.0.0//!//! [dependencies]//! captcha = "0.0.9"use captcha::filters::{Dots, Noise, Wave};use captcha::Captcha;use std::collections::HashMap;/// A new captcha of `length` characters (4 to 8): `{ image, answer }`. `image` is a `data:image/png;base64,...` URL for an/// `<img src>`, 220 by 110 pixels; keep `answer` on the server (in the session), never in the page. `hard` adds more noise and waves.pub fn captcha_new(length: i64, hard: bool) -> Result<HashMap<String, String>, String> { let n = length.clamp(4, 8) as u32; let mut c = Captcha::new(); c.add_chars(n); if hard { c.apply_filter(Noise::new(0.5)).apply_filter(Wave::new(2.0, 20.0)).apply_filter(Wave::new(2.0, 20.0).vertical()).apply_filter(Dots::new(15)); } else { c.apply_filter(Noise::new(0.3)).apply_filter(Wave::new(2.0, 12.0)).apply_filter(Dots::new(6)); } c.view(220, 110); let answer = c.chars_as_string(); let image = c.as_base64().ok_or("the picture could not be made")?; Ok(HashMap::from([ ("image".to_string(), format!("data:image/png;base64,{}", image)), ("answer".to_string(), answer), ]))}/// Whether what the visitor typed is the answer: spaces around it ignored, and capitals too, since some letters look alike in both./// An empty answer on either side is false.pub fn captcha_check(answer: &str, typed: &str) -> bool { let (a, t) = (answer.trim().to_lowercase(), typed.trim().to_lowercase()); !a.is_empty() && a.len() == t.len() && a.bytes().zip(t.bytes()).fold(0u8, |acc, (x, y)| acc | (x ^ y)) == 0}Related
password_strength.qwer · 1.0.0How guessable a password is (zxcvbn): a score from 0 to 4, a warning and suggestions, and how long it would take to crack.6 views · 8 downloadsCaptcha checks captcha_verify.qwer · 1.0.0Server-side checks of Cloudflare Turnstile, hCaptcha and reCAPTCHA v2 and v3 answers with one call and one result shape, the hostname, action and score checked, and the widget's HTML for the form.6 views · 7 downloadsPDF forms pdf_forms.qwer · 1.0.0PDF forms: the fields listed with their types, values and choices, filled from a map with their appearances drawn, and flattened so they cannot be changed.8 views · 6 downloadsCSRF tokens csrf_tokens.qwer · 1.0.0CSRF protection for forms and fetch calls: tokens signed for one session that expire, the signed double-submit cookie check, and the Origin, Referer and Sec-Fetch-Site checks.7 views · 7 downloadsPassphrases passphrase.qwer · 1.0.0Diceware passphrases from the EFF word lists, easy to type and remember and hard to guess, with their strength in bits.7 views · 7 downloadsPwned passwords pwned.qwer · 1.0.0Have I Been Pwned's Pwned Passwords by k-anonymity: only 5 characters of the SHA-1 leave the server, the answer is checked here.8 views · 9 downloadsThread 0 posts
On Captcha: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.