···1+MIT License
2+3+Copyright (c) 2024-2025 Front Matter
4+Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>
5+6+Permission is hereby granted, free of charge, to any person obtaining a copy
7+of this software and associated documentation files (the "Software"), to deal
8+in the Software without restriction, including without limitation the rights
9+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+copies of the Software, and to permit persons to whom the Software is
11+furnished to do so, subject to the following conditions:
12+13+The above copyright notice and this permission notice shall be included in all
14+copies or substantial portions of the Software.
15+16+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+SOFTWARE.
···1+(* roguedoi.ml - Generate random DOI identifiers with Crockford base32 encoding *)
2+3+let generate_doi prefix length split =
4+ Random.self_init ();
5+ let suffix = Crockford.generate ~length ~split_every:split ~checksum:true () in
6+ Printf.printf "https://doi.org/%s/%s\n%!" prefix suffix
7+8+let () =
9+ let open Cmdliner in
10+11+ let prefix =
12+ let doc = "DOI prefix to use (e.g., 10.59350)" in
13+ Arg.(value & opt string "10.59350" & info ["p"; "prefix"] ~docv:"PREFIX" ~doc)
14+ in
15+16+ let length =
17+ let doc = "Total length of the generated suffix (including checksum)" in
18+ Arg.(value & opt int 10 & info ["l"; "length"] ~docv:"LENGTH" ~doc)
19+ in
20+21+ let split =
22+ let doc = "Split the suffix every N characters with hyphens (0 = no splitting)" in
23+ Arg.(value & opt int 5 & info ["s"; "split"] ~docv:"SPLIT" ~doc)
24+ in
25+26+ let generate_cmd =
27+ let doc = "Generate a random DOI with Crockford base32 encoding" in
28+ let info = Cmd.info "roguedoi" ~version:"0.1.0" ~doc in
29+ Cmd.v info Term.(const generate_doi $ prefix $ length $ split)
30+ in
31+32+ exit (Cmd.eval generate_cmd)
+32
crockford.opam
···00000000000000000000000000000000
···1+# This file is generated by dune, edit dune-project instead
2+opam-version: "2.0"
3+synopsis: "Crockford Base32 encoding for OCaml"
4+description:
5+ "An OCaml implementation of Douglas Crockford's Base32 encoding with ISO 7064 checksum support. Provides encoding and decoding of int64 values to URI-friendly base32 strings, with optional checksum validation, padding, splitting, and random ID generation."
6+maintainer: ["Anil Madhavapeddy <anil@recoil.org>"]
7+authors: ["Anil Madhavapeddy"]
8+license: "ISC"
9+homepage: "https://tangled.org/@anil.recoil.org/ocaml-crockford"
10+bug-reports: "https://tangled.org/@anil.recoil.org/ocaml-crockford/issues"
11+depends: [
12+ "dune" {>= "3.20"}
13+ "ocaml" {>= "4.14.1"}
14+ "odoc" {with-doc}
15+ "alcotest" {with-test & >= "1.9.0"}
16+ "cmdliner" {>= "1.1.0"}
17+]
18+build: [
19+ ["dune" "subst"] {dev}
20+ [
21+ "dune"
22+ "build"
23+ "-p"
24+ name
25+ "-j"
26+ jobs
27+ "@install"
28+ "@runtest" {with-test}
29+ "@doc" {with-doc}
30+ ]
31+]
32+x-maintenance-intent: ["(latest)"]
+26
dune-project
···00000000000000000000000000
···1+(lang dune 3.20)
2+3+(name crockford)
4+5+(generate_opam_files true)
6+7+(license ISC)
8+(authors "Anil Madhavapeddy")
9+(homepage "https://tangled.org/@anil.recoil.org/ocaml-crockford")
10+(maintainers "Anil Madhavapeddy <anil@recoil.org>")
11+(bug_reports "https://tangled.org/@anil.recoil.org/ocaml-crockford/issues")
12+(maintenance_intent "(latest)")
13+14+(package
15+ (name crockford)
16+ (synopsis "Crockford Base32 encoding for OCaml")
17+ (description
18+ "An OCaml implementation of Douglas Crockford's Base32 encoding with \
19+ ISO 7064 checksum support. Provides encoding and decoding of int64 values \
20+ to URI-friendly base32 strings, with optional checksum validation, padding, \
21+ splitting, and random ID generation.")
22+ (depends
23+ (ocaml (>= 4.14.1))
24+ (odoc :with-doc)
25+ (alcotest (and :with-test (>= 1.9.0)))
26+ (cmdliner (>= 1.1.0))))