MTID (Multi-length Triplet ID)
The mtid crate has been renamed to caretta-id. Please use the caretta-id crate instead.
A human-friendly identifier format based on 3-character blocks ("triplet"). This crate provides multiple fixed-length variants:
Stid: Single triplet ID (e.g.123)Dtid: Double Triplet ID (e.g.456-789)Ttid: Triple Triplet ID (e.g.abc-def-ghj)Qtid: Quadruple triplet ID (e.g.kmn-pqr-stv-wxy)
For a language agnostic specification of the MTID format, see SPECS.md
Quick Start
use Dtid;
let id = random;
println!; // e.g. "1a2-b3c"
Why MTID?
Traditional identifier systems face challenges in distributed environments:
- Sequential numbers (like GitHub issue numbers) cause collisions in distributed systems
- UUIDs are too long and not human-friendly
- Short hashes (like Git commit hashes) lack standardization
MTID bridges the gap between human readability and technical requirements.
Which length should I use?
- DTID(Double length triplet ID) is recommended for the personal data because this is short enough to satisfy the Magic Number 7±2 principle and have enough range of value (for the data entered manually by individuals (such as pocketbooks, journals, or activity logs)).
- STID(Single length triplet ID) is recommended if the data is expected to be so few that they can be counted.
- TTID(Triple length triplet ID) is recommended if it is expected that one or more data will be added every second.
- QTID(Quadruple length Triplet ID) is recommended if, the number of data could potentially become so large that it's impossible to predict (for example, in a multi-user application where the IDs must be unique across users).
Installation
Add this to your Cargo.toml:
[]
= "0.6"
# With optional features
= { = "0.6", = ["arbitrary", "serde", "rusqlite", "sea-orm", "prost"] }
For no_std Environments
This crate support no_std.
For no_std environment, you'll need to disable default features.
[]
= { = "0.6", = false }
Features
- Human-friendly: Easy to read, type, and communicate
- Collision-resistant: Sufficient entropy for distributed systems
- Compact: Shorter than UUIDs while maintaining uniqueness
- Type-safe: Rust implementation with strong typing
- Multiple integrations: Support for serde, rusqlite, sea-orm, and protobuf
Optional Feature Flags
arbitrary:arbitrary::Arbitrarysupport for fuzzing tests.serde: Serialization/deserialization supportrusqlite: SQLite database integrationsea-orm: SeaORM ORM integrationprost: Protocol Buffers support
Examples
use ;
// Generate random MTID
let stid = random;
let dtid = random;
let ttid = random;
let qtid = random;
// '123', '456-789', 'abc-def-ghj', 'kmn-pqr-stv-wxy'
println!;
// Parse from string
let valid_id: Dtid = "012-tvw".parse?;
// The code without delimiter is valid.
let valid_id_without_delimiter: Dtid = "012tvw".parse?;
assert_eq!;
// When decoding from BASE32, ambiguous characters (1/l/I, 0/o, v/u, -/_) are treated as 1, 0, v, and - respectively, so they do not cause errors.
let also_valid_id: Dtid = "ol2_tuw".parse?;
assert_eq!;
// Convert to/from integer
let num: u32 = valid_id.into;
let id_from_int: Dtid = num.try_into?;
assert_eq!;
// Lossy conversion from oversized int is allowed.
let id_from_overflowed_int = from_uint_lossy;
assert_eq!;
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.