Short ids
Short ids for URLs made from your database's numbers and read back (Sqids): your own alphabet, a minimum length, no rude words, and typos never reaching another row.
Version 1.0.0 · 4 functions · 1 crate
Functions
What use short_ids.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use short_id_encode, short_id_decode from short_ids (Quillo 0.6).
short_id_encode(numbers: list, alphabet: str, min_length: int) → stror an errorAn id for numbers (whole numbers from 0, one or several: [1042] or [user, post]), at least min_length characters, written with alphabet ("" for a-z, A-Z and 0-9; shuffle it, so others cannot read your ids back with the default). It hides numbers from casual eyes only: it is not encryption.
short_id_decode(id: str, alphabet: str, min_length: int) → listor an errorThe numbers in an id made by short_id_encode with the same alphabet and min_length, or an empty list when it is not one of yours (ids are checked to be the one way of writing their numbers, so a typo cannot reach another row).
short_id(number: int) → stror an errorOne number's id with the default alphabet, at least 6 characters: short_id(1042).
short_id_number(id: str) → int?or an errorThe number of an id made by short_id, or null when it is not one.
Get it
$ quillo install short_ids # short_ids.qwer into this folder$ quillo install short_ids --example # and its example, short_ids.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/short_ids.qwer$ curl -O https://quillolang.org/plugins/files/short_ids.qweThen, in your program, all of it or only what you call:
use short_ids.qweruse short_id_encode, short_id_decode from short_ids // Quillo 0.6: only theseIt uses this crate, which cargo fetches the first time the plugin is built:
sqids = "0.4"Example
// Order pages at /orders/<short id> instead of /orders/1042, and the id read back to find the row.//// quillo run short_ids.qwe then open http://localhost:8080/ordersuse "short_ids.qwer"// Your own shuffle of the alphabet, kept with the program: ids made with it read back only with it.let ALPHABET = "k3G7QAe51FCsPW92uEOyq4Bg6Sp8YzVTmnU0liwDdHXLajZrfxNvobJIRchMKt"let orders = [{ id: 1042, total: 99 }, { id: 1043, total: 15 }]route GET /orders = orders | map((o) => { url: `/orders/${short_id_encode([o.id], ALPHABET, 6)?}`, total: o.total })route GET /orders/:code { let ids = short_id_decode(code, ALPHABET, 6)? if len(ids) != 1 { reply 404 "No such order" } find(orders, (o) => o.id == ids[0]) ?? { error: "gone" }}route GET /plain = { id: short_id(1042)?, back: short_id_number(short_id(1042)?)?, pair: short_id_encode([7, 99], "", 0)?, junk: short_id_number("nope!")? }$ quillo run short_ids.qwe$ curl 'localhost:8080/orders'$ curl 'localhost:8080/orders/QKGlWg'$ curl 'localhost:8080/plain'Source
//! Short ids for URLs made from your database's numbers and read back (Sqids, formerly Hashids): /orders/86Rf07 instead of /orders/1042, with your own alphabet and no rude words.//! version: 1.0.0//!//! [dependencies]//! sqids = "0.4"use sqids::Sqids;use std::collections::HashMap;use std::sync::{Arc, Mutex};fn coder(alphabet: &str, min_length: i64) -> Result<Arc<Sqids>, String> { static CACHE: Mutex<Option<HashMap<(String, u8), Arc<Sqids>>>> = Mutex::new(None); let min = min_length.clamp(0, 255) as u8; let mut g = CACHE.lock().unwrap_or_else(|e| e.into_inner()); let map = g.get_or_insert_with(HashMap::new); if let Some(s) = map.get(&(alphabet.to_string(), min)) { return Ok(s.clone()); } let mut b = Sqids::builder().min_length(min); if !alphabet.is_empty() { b = b.alphabet(alphabet.chars().collect()); } let s = Arc::new(b.build().map_err(|e| e.to_string())?); if map.len() < 100 { map.insert((alphabet.to_string(), min), s.clone()); } Ok(s)}/// An id for `numbers` (whole numbers from 0, one or several: [1042] or [user, post]), at least `min_length` characters, written with `alphabet` ("" for a-z, A-Z and 0-9; shuffle it, so others cannot read your ids back with the default). It hides numbers from casual eyes only: it is not encryption.pub fn short_id_encode(numbers: Vec<i64>, alphabet: &str, min_length: i64) -> Result<String, String> { if numbers.is_empty() || numbers.len() > 100 || numbers.iter().any(|&n| n < 0) { return Err("1 to 100 numbers, none negative".into()); } let ns: Vec<u64> = numbers.iter().map(|&n| n as u64).collect(); coder(alphabet, min_length)?.encode(&ns).map_err(|e| e.to_string())}/// The numbers in an id made by `short_id_encode` with the same `alphabet` and `min_length`, or an empty list when it is not one of yours (ids are checked to be the one way of writing their numbers, so a typo cannot reach another row).pub fn short_id_decode(id: &str, alphabet: &str, min_length: i64) -> Result<Vec<i64>, String> { if id.len() > 1000 { return Ok(vec![]); } let c = coder(alphabet, min_length)?; let ns = c.decode(id); if ns.is_empty() || ns.iter().any(|&n| n > i64::MAX as u64) || c.encode(&ns).ok().as_deref() != Some(id) { return Ok(vec![]); } Ok(ns.into_iter().map(|n| n as i64).collect())}/// One number's id with the default alphabet, at least 6 characters: `short_id(1042)`.pub fn short_id(number: i64) -> Result<String, String> { short_id_encode(vec![number], "", 6)}/// The number of an id made by `short_id`, or null when it is not one.pub fn short_id_number(id: &str) -> Result<Option<i64>, String> { let ns = short_id_decode(id, "", 6)?; Ok(if ns.len() == 1 { Some(ns[0]) } else { None })}Related
typeid.qwer · 1.0.0TypeIDs such as user_01h455vb4pex5vsknk084sn02q: a type prefix and a UUIDv7 in base32, made, read back to their UUID and time, and checked against the type a URL expects.6 views · 7 downloadsCUID2 cuid2.qwer · 1.0.0CUID2 ids: secure, collision-resistant, starting with a letter, of the length you choose, that give away neither the time nor a count; and a check that a string is one.7 views · 7 downloadsKSUID ksuid.qwer · 1.0.0KSUIDs, Segment's K-Sortable Unique IDs: 27 base62 characters sorted by the second they were made, with 128 random bits; made, read back and checked.8 views · 7 downloadsUUID tools uuid_tools.qwer · 1.0.0UUIDs beyond the random uuid(): version 7 sorted by time for database keys, versions 5 and 3 that give the same id for the same name, and any UUID read with its version and time.7 views · 6 downloadsNano ID nanoid.qwer · 1.0.0Short random ids for links, invites and coupon codes: Nano ID with secure random, your own alphabet and length, readable codes for print, and the odds of a collision.7 views · 7 downloadsReadable ids human_ids.qwer · 1.0.0Readable ids such as brave-blue-fox for projects, preview URLs and invite codes: random, alliterating, or always the same name for a given number.7 views · 7 downloadsThread 0 posts
On Short ids: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.