foundation_ur/lib.rs
1// SPDX-FileCopyrightText: © 2023 Foundation Devices, Inc. <hello@foundationdevices.com>
2// SPDX-FileCopyrightText: © 2020 Dominik Spicher <dominikspicher@gmail.com>
3// SPDX-License-Identifier: MIT
4
5//! `ur` is a crate to interact with ["Uniform Resources (UR)"] encodings
6//! of binary data.
7//!
8//! The encoding scheme is optimized for transport in URIs and QR codes.
9//!
10//! The [encoder](BaseEncoder) allows a byte payload to be transmitted in
11//! multiple stages, respecting maximum size requirements. Under the hood, a
12//! [`fountain`] encoder is used to create an unbounded stream of URIs, subsets
13//! of which can be recombined at the receiving side into the payload.
14//!
15//! For example:
16//!
17//! ```
18//! # use foundation_ur::{HeaplessDecoder, HeaplessEncoder};
19//! # let mut encoder: HeaplessEncoder<32, 32> = HeaplessEncoder::new();
20//! # let mut decoder: HeaplessDecoder<100, 32, 32, 32, 32, 32> = HeaplessDecoder::new();
21//! const MAX_FRAGMENT_LENGTH: usize = 5;
22//!
23//! let data = "Ten chars!".repeat(10);
24//!
25//! encoder.start("bytes", data.as_bytes(), MAX_FRAGMENT_LENGTH);
26//! assert_eq!(
27//! encoder.next_part().to_string(),
28//! "ur:bytes/1-20/lpadbbcsiecyvdidatkpfeghihjtcxiabdfevlms"
29//! );
30//!
31//! while !decoder.is_complete() {
32//! let sequence = encoder.current_sequence();
33//! let part = encoder.next_part();
34//! // Simulate some communication loss
35//! if sequence & 1 > 0 {
36//! decoder.receive(part).unwrap();
37//! }
38//! }
39//! assert_eq!(decoder.message().unwrap().as_deref(), Some(data.as_bytes()));
40//! ```
41//!
42//! ["Uniform Resources (UR)"]: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
43//! [`fountain`]: https://en.wikipedia.org/wiki/Fountain_code
44//!
45//! The following useful building blocks are also part of the public API:
46//!
47//! - The [`bytewords`] module contains functionality to encode byte payloads
48//! into a suitable alphabet, achieving hexadecimal byte-per-character
49//! efficiency.
50//!
51//! - The [`fountain`] module provides an implementation of a fountain
52//! encoder, which splits up a byte payload into multiple segments and
53//! emits an unbounded stream of parts which can be recombined at the
54//! receiving decoder side.
55#![forbid(unsafe_code)]
56#![cfg_attr(not(feature = "std"), no_std)]
57#![warn(missing_docs)]
58
59#[cfg(feature = "alloc")]
60extern crate alloc;
61extern crate core;
62
63pub mod bytewords;
64pub mod collections;
65pub mod fountain;
66
67mod len;
68mod ur;
69mod xoshiro;
70
71pub use self::len::*;
72pub use self::ur::*;
73
74const CRC32: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_ISO_HDLC);
75
76#[test]
77fn test_crc() {
78 assert_eq!(CRC32.checksum(b"Hello, world!"), 0xebe6_c6e6);
79 assert_eq!(CRC32.checksum(b"Wolf"), 0x598c_84dc);
80}