• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ia0 / data-encoding / #1030

28 Jun 2025 04:09PM UTC coverage: 52.853%. Remained the same
#1030

push

web-flow
Fix lint in xtask (#144)

491 of 929 relevant lines covered (52.85%)

2.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
lib/v3/src/lib.rs
1
//! Efficient and customizable data-encoding functions like base64, base32, and hex
2
#![doc = ""]
3
#![doc = include_str!("../README.md")]
4
#![no_std]
5
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
6

7
#[cfg(feature = "alloc")]
8
extern crate alloc;
9
#[cfg(feature = "std")]
10
extern crate std;
11

12
#[cfg(feature = "alloc")]
13
use alloc::borrow::{Cow, ToOwned};
14
#[cfg(feature = "alloc")]
15
use alloc::string::String;
16
#[cfg(feature = "alloc")]
17
use alloc::vec;
18
#[cfg(feature = "alloc")]
19
use alloc::vec::Vec;
20
use core::convert::TryInto;
21
use core::marker::PhantomData;
22
use core::mem::MaybeUninit;
23

24
macro_rules! check {
25
    ($e: expr, $c: expr) => {
26
        if !$c {
27
            return Err($e);
28
        }
29
    };
30
}
31

32
/// Type-level bit-width of an encoding.
33
pub trait BitWidth: sealed::BitWidth {}
34

35
/// Type-level bool.
36
pub trait Bool: sealed::Bool {}
37

38
mod sealed {
39
    pub trait BitWidth {
40
        const VAL: usize;
41
    }
42

43
    pub trait Bool {
44
        type If<Then: Copy, Else: Copy>: Copy;
45
        const VAL: bool;
46
        fn open<Then: Copy, Else: Copy>(cond: Self::If<Then, Else>) -> If<Then, Else>;
47
        fn make<Then: Copy, Else: Copy>(
48
            then: impl FnOnce() -> Then, else_: impl FnOnce() -> Else,
49
        ) -> Self::If<Then, Else>;
50
    }
51

52
    #[derive(Debug, Copy, Clone)]
53
    pub enum If<Then, Else> {
54
        Then(Then),
55
        Else(Else),
56
    }
57
}
58
use sealed::If;
59

60
macro_rules! new_bit_width {
61
    ($(($N:ident, $v:expr, $b:literal),)*) => {
62
        $(
63
            #[doc = concat!(" Bit-width of ", $b, " encodings.")]
64
            #[derive(Debug)]
65
            pub enum $N {}
66
            impl BitWidth for $N {}
67
            impl sealed::BitWidth for $N { const VAL: usize = $v; }
68
        )*
69
    };
70
}
71
new_bit_width![
72
    (Bit1, 1, "base2"),
73
    (Bit2, 2, "base4"),
74
    (Bit3, 3, "base8"),
75
    (Bit4, 4, "base16"),
76
    (Bit5, 5, "base32"),
77
    (Bit6, 6, "base64"),
78
];
79

80
/// Type-level false.
81
#[derive(Debug)]
82
pub enum False {}
83
impl Bool for False {}
84
impl sealed::Bool for False {
85
    type If<Then: Copy, Else: Copy> = Else;
86
    const VAL: bool = false;
87
    fn open<Then: Copy, Else: Copy>(cond: Self::If<Then, Else>) -> If<Then, Else> {
×
88
        If::Else(cond)
×
89
    }
90
    fn make<Then: Copy, Else: Copy>(
91
        _then: impl FnOnce() -> Then, else_: impl FnOnce() -> Else,
92
    ) -> Self::If<Then, Else> {
93
        else_()
×
94
    }
95
}
96

97
/// Type-level true.
98
#[derive(Debug, Copy, Clone)]
99
pub enum True {}
100
impl Bool for True {}
101
impl sealed::Bool for True {
102
    type If<Then: Copy, Else: Copy> = Then;
103
    const VAL: bool = true;
104
    fn open<Then: Copy, Else: Copy>(cond: Self::If<Then, Else>) -> If<Then, Else> {
×
105
        If::Then(cond)
×
106
    }
107
    fn make<Then: Copy, Else: Copy>(
108
        then: impl FnOnce() -> Then, _else: impl FnOnce() -> Else,
109
    ) -> Self::If<Then, Else> {
110
        then()
×
111
    }
112
}
113

114
unsafe fn cast<Bit: BitWidth, Msb: Bool, Pad: Bool, Wrap: Bool, Ignore: Bool>(
115
    base: &DynEncoding,
116
) -> &Encoding<Bit, Msb, Pad, Wrap, Ignore> {
117
    let ptr = core::ptr::from_ref(base).cast::<Encoding<Bit, Msb, Pad, Wrap, Ignore>>();
×
118
    unsafe { &*ptr }
×
119
}
120

121
macro_rules! dispatch {
122
    ($dyn:ident $($body: tt)*) => {
123
        dispatch!([] Bit $dyn $($body)*)
124
    };
125
    ([] Bit $dyn:ident $($body:tt)*) => {
126
        match $dyn.bit() {
127
            1 => dispatch!([Bit1] Msb $dyn $($body)*),
128
            2 => dispatch!([Bit2] Msb $dyn $($body)*),
129
            3 => dispatch!([Bit3] Msb $dyn $($body)*),
130
            4 => dispatch!([Bit4] Msb $dyn $($body)*),
131
            5 => dispatch!([Bit5] Msb $dyn $($body)*),
132
            6 => dispatch!([Bit6] Msb $dyn $($body)*),
133
            _ => unreachable!(),
134
        }
135
    };
136
    ([$($gen:ty),*] Msb $dyn:ident $($body:tt)*) => {
137
        match $dyn.msb() {
138
            false => dispatch!([$($gen),*, False] Pad $dyn $($body)*),
139
            true => dispatch!([$($gen),*, True] Pad $dyn $($body)*),
140
        }
141
    };
142
    ([$($gen:ty),*] Pad $dyn:ident $($body:tt)*) => {
143
        match $dyn.pad().is_some() {
144
            false => dispatch!([$($gen),*, False] Wrap $dyn $($body)*),
145
            true => dispatch!([$($gen),*, True] Wrap $dyn $($body)*),
146
        }
147
    };
148
    ([$($gen:ty),*] Wrap $dyn:ident $($body:tt)*) => {
149
        match $dyn.wrap().is_some() {
150
            false => dispatch!([$($gen),*, False] Ignore $dyn $($body)*),
151
            true => dispatch!([$($gen),*, True] Ignore $dyn $($body)*),
152
        }
153
    };
154
    ([$($gen:ty),*] Ignore $dyn:ident $($body:tt)*) => {
155
        match $dyn.has_ignore() {
156
            false => dispatch!({ $($gen),*, False } $dyn $($body)*),
157
            true => dispatch!({ $($gen),*, True } $dyn $($body)*),
158
        }
159
    };
160
    ({ $($gen:ty),* } $dyn:ident $($body:tt)*) => {
161
        unsafe { cast::<$($gen),*>($dyn) } $($body)*
162
    };
163
}
164

165
unsafe fn chunk_unchecked<T>(x: &[T], n: usize, i: usize) -> &[T] {
×
166
    debug_assert!((i + 1) * n <= x.len());
×
167
    unsafe { core::slice::from_raw_parts(x.as_ptr().add(n * i), n) }
×
168
}
169

170
unsafe fn chunk_mut_unchecked<T>(x: &mut [T], n: usize, i: usize) -> &mut [T] {
×
171
    debug_assert!((i + 1) * n <= x.len());
×
172
    unsafe { core::slice::from_raw_parts_mut(x.as_mut_ptr().add(n * i), n) }
×
173
}
174

175
// TODO(https://github.com/rust-lang/rust/issues/79995): Use write_slice() instead.
176
unsafe fn copy_from_slice(dst: &mut [MaybeUninit<u8>], src: &[u8]) {
177
    dst.copy_from_slice(unsafe { &*(core::ptr::from_ref(src) as *const [MaybeUninit<u8>]) });
178
}
179

180
// TODO(https://github.com/rust-lang/rust/issues/63569): Use slice_assume_init_mut() instead.
181
unsafe fn slice_assume_init_mut(xs: &mut [MaybeUninit<u8>]) -> &mut [u8] {
182
    unsafe { &mut *(core::ptr::from_mut(xs) as *mut [u8]) }
183
}
184

185
unsafe fn slice_uninit_mut(xs: &mut [u8]) -> &mut [MaybeUninit<u8>] {
186
    unsafe { &mut *(core::ptr::from_mut(xs) as *mut [MaybeUninit<u8>]) }
187
}
188

189
#[cfg(feature = "alloc")]
190
fn reserve_spare(xs: &mut Vec<u8>, n: usize) -> &mut [MaybeUninit<u8>] {
191
    xs.reserve(n);
192
    &mut xs.spare_capacity_mut()[.. n]
193
}
194

195
fn floor(x: usize, m: usize) -> usize {
196
    x / m * m
197
}
198

199
#[inline]
200
fn vectorize<F: FnMut(usize)>(n: usize, bs: usize, mut f: F) {
×
201
    for k in 0 .. n / bs {
×
202
        for i in k * bs .. (k + 1) * bs {
×
203
            f(i);
×
204
        }
205
    }
206
    for i in floor(n, bs) .. n {
×
207
        f(i);
×
208
    }
209
}
210

211
/// Decoding error kind
212
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
213
pub enum DecodeKind {
214
    /// Invalid length
215
    Length,
216

217
    /// Invalid symbol
218
    Symbol,
219

220
    /// Non-zero trailing bits
221
    Trailing,
222

223
    /// Invalid padding length
224
    Padding,
225
}
226

227
impl core::fmt::Display for DecodeKind {
228
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
229
        let description = match self {
230
            DecodeKind::Length => "invalid length",
231
            DecodeKind::Symbol => "invalid symbol",
232
            DecodeKind::Trailing => "non-zero trailing bits",
233
            DecodeKind::Padding => "invalid padding length",
234
        };
235
        write!(f, "{description}")
236
    }
237
}
238

239
/// Decoding error
240
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
241
pub struct DecodeError {
242
    /// Error position
243
    ///
244
    /// This position is always a valid input position and represents the first encountered error.
245
    pub position: usize,
246

247
    /// Error kind
248
    pub kind: DecodeKind,
249
}
250

251
#[cfg(feature = "std")]
252
impl std::error::Error for DecodeError {}
253

254
impl core::fmt::Display for DecodeError {
255
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
256
        write!(f, "{} at {}", self.kind, self.position)
257
    }
258
}
259

260
/// Decoding error with partial result
261
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
262
pub struct DecodePartial {
263
    /// Number of bytes read from input
264
    ///
265
    /// This number does not exceed the error position: `read <= error.position`.
266
    pub read: usize,
267

268
    /// Number of bytes written to output
269
    ///
270
    /// This number does not exceed the decoded length: `written <= decode_len(read)`.
271
    pub written: usize,
272

273
    /// Decoding error
274
    pub error: DecodeError,
275
}
276

277
const INVALID: u8 = 128;
278
const IGNORE: u8 = 129;
279
const PADDING: u8 = 130;
280

281
fn order(msb: bool, n: usize, i: usize) -> usize {
282
    if msb { n - 1 - i } else { i }
283
}
284

285
#[inline]
286
fn enc(bit: usize) -> usize {
×
287
    match bit {
×
288
        1 | 2 | 4 => 1,
×
289
        3 | 6 => 3,
×
290
        5 => 5,
×
291
        _ => unreachable!(),
292
    }
293
}
294

295
#[inline]
296
fn dec(bit: usize) -> usize {
×
297
    enc(bit) * 8 / bit
×
298
}
299

300
fn encode_len<Bit: BitWidth>(len: usize) -> usize {
×
301
    (8 * len).div_ceil(Bit::VAL)
×
302
}
303

304
fn encode_block<Bit: BitWidth, Msb: Bool>(
305
    symbols: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
306
) {
307
    debug_assert!(input.len() <= enc(Bit::VAL));
×
308
    debug_assert_eq!(output.len(), encode_len::<Bit>(input.len()));
×
309
    let bit = Bit::VAL;
×
310
    let msb = Msb::VAL;
×
311
    let mut x = 0u64;
×
312
    for (i, input) in input.iter().enumerate() {
×
313
        x |= u64::from(*input) << (8 * order(msb, enc(bit), i));
×
314
    }
315
    for (i, output) in output.iter_mut().enumerate() {
×
316
        let y = x >> (bit * order(msb, dec(bit), i));
×
317
        let _ = output.write(symbols[(y & 0xff) as usize]);
×
318
    }
319
}
320

321
fn encode_mut<Bit: BitWidth, Msb: Bool>(
322
    symbols: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
323
) {
324
    debug_assert_eq!(output.len(), encode_len::<Bit>(input.len()));
×
325
    let bit = Bit::VAL;
×
326
    let enc = enc(bit);
×
327
    let dec = dec(bit);
×
328
    let n = input.len() / enc;
×
329
    let bs = match bit {
×
330
        5 => 2,
×
331
        6 => 4,
×
332
        _ => 1,
×
333
    };
334
    vectorize(n, bs, |i| {
×
335
        let input = unsafe { chunk_unchecked(input, enc, i) };
×
336
        let output = unsafe { chunk_mut_unchecked(output, dec, i) };
×
337
        encode_block::<Bit, Msb>(symbols, input, output);
×
338
    });
339
    encode_block::<Bit, Msb>(symbols, &input[enc * n ..], &mut output[dec * n ..]);
×
340
}
341

342
// Fails if an input character does not translate to a symbol. The error is the
343
// lowest index of such character. The output is not written to.
344
fn decode_block<Bit: BitWidth, Msb: Bool>(
345
    values: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
346
) -> Result<(), usize> {
347
    debug_assert!(output.len() <= enc(Bit::VAL));
×
348
    debug_assert_eq!(input.len(), encode_len::<Bit>(output.len()));
×
349
    let bit = Bit::VAL;
×
350
    let msb = Msb::VAL;
×
351
    let mut x = 0u64;
×
352
    for j in 0 .. input.len() {
×
353
        let y = values[input[j] as usize];
×
354
        check!(j, y < 1 << bit);
×
355
        x |= u64::from(y) << (bit * order(msb, dec(bit), j));
×
356
    }
357
    for (j, output) in output.iter_mut().enumerate() {
×
358
        let _ = output.write((x >> (8 * order(msb, enc(bit), j)) & 0xff) as u8);
×
359
    }
360
    Ok(())
×
361
}
362

363
// Fails if an input character does not translate to a symbol. The error `pos`
364
// is the lowest index of such character. The output is valid up to `pos / dec *
365
// enc` excluded.
366
fn decode_mut<Bit: BitWidth, Msb: Bool>(
367
    values: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
368
) -> Result<(), usize> {
369
    debug_assert_eq!(input.len(), encode_len::<Bit>(output.len()));
×
370
    let bit = Bit::VAL;
×
371
    let enc = enc(bit);
×
372
    let dec = dec(bit);
×
373
    let n = input.len() / dec;
×
374
    for i in 0 .. n {
×
375
        let input = unsafe { chunk_unchecked(input, dec, i) };
×
376
        let output = unsafe { chunk_mut_unchecked(output, enc, i) };
×
377
        decode_block::<Bit, Msb>(values, input, output).map_err(|e| dec * i + e)?;
×
378
    }
379
    decode_block::<Bit, Msb>(values, &input[dec * n ..], &mut output[enc * n ..])
×
380
        .map_err(|e| dec * n + e)
×
381
}
382

383
// Fails if there are non-zero trailing bits.
384
fn check_trail<Bit: BitWidth, Msb: Bool>(
385
    ctb: bool, values: &[u8; 256], input: &[u8],
386
) -> Result<(), ()> {
387
    if 8 % Bit::VAL == 0 || !ctb {
×
388
        return Ok(());
×
389
    }
390
    let trail = Bit::VAL * input.len() % 8;
×
391
    if trail == 0 {
×
392
        return Ok(());
×
393
    }
394
    let mut mask = (1 << trail) - 1;
×
395
    if !Msb::VAL {
×
396
        mask <<= Bit::VAL - trail;
×
397
    }
398
    check!((), values[input[input.len() - 1] as usize] & mask == 0);
×
399
    Ok(())
×
400
}
401

402
// Fails if the padding length is invalid. The error is the index of the first
403
// padding character.
404
fn check_pad<Bit: BitWidth>(values: &[u8; 256], input: &[u8]) -> Result<usize, usize> {
×
405
    let bit = Bit::VAL;
×
406
    debug_assert_eq!(input.len(), dec(bit));
×
407
    let is_pad = |x: &&u8| values[**x as usize] == PADDING;
×
408
    let count = input.iter().rev().take_while(is_pad).count();
×
409
    let len = input.len() - count;
×
410
    check!(len, len > 0 && bit * len % 8 < bit);
×
411
    Ok(len)
×
412
}
413

414
fn encode_base_len<Bit: BitWidth>(len: usize) -> usize {
×
415
    encode_len::<Bit>(len)
×
416
}
417

418
fn encode_base<Bit: BitWidth, Msb: Bool>(
419
    symbols: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
420
) {
421
    debug_assert_eq!(output.len(), encode_base_len::<Bit>(input.len()));
×
422
    encode_mut::<Bit, Msb>(symbols, input, output);
×
423
}
424

425
fn encode_pad_len<Bit: BitWidth, Pad: Bool>(len: usize) -> usize {
×
426
    match Pad::VAL {
×
427
        false => encode_base_len::<Bit>(len),
×
428
        true => len.div_ceil(enc(Bit::VAL)) * dec(Bit::VAL),
×
429
    }
430
}
431

432
fn encode_pad<Bit: BitWidth, Msb: Bool, Pad: Bool>(
433
    symbols: &[u8; 256], pad: Pad::If<u8, ()>, input: &[u8], output: &mut [MaybeUninit<u8>],
434
) {
435
    let pad = match Pad::open(pad) {
×
436
        If::Then(x) => x,
×
437
        If::Else(()) => return encode_base::<Bit, Msb>(symbols, input, output),
×
438
    };
439
    debug_assert_eq!(output.len(), encode_pad_len::<Bit, Pad>(input.len()));
×
440
    let olen = encode_base_len::<Bit>(input.len());
×
441
    encode_base::<Bit, Msb>(symbols, input, &mut output[.. olen]);
×
442
    for output in output.iter_mut().skip(olen) {
×
443
        let _ = output.write(pad);
×
444
    }
445
}
446

447
fn encode_wrap_len<Bit: BitWidth, Pad: Bool, Wrap: Bool>(
448
    wrap: Wrap::If<(usize, &[u8]), ()>, ilen: usize,
449
) -> usize {
450
    let olen = encode_pad_len::<Bit, Pad>(ilen);
×
451
    match Wrap::open(wrap) {
×
452
        If::Then((col, end)) => olen + end.len() * olen.div_ceil(col),
×
453
        If::Else(()) => olen,
×
454
    }
455
}
456

457
fn encode_wrap_mut<Bit: BitWidth, Msb: Bool, Pad: Bool, Wrap: Bool>(
458
    symbols: &[u8; 256], pad: Pad::If<u8, ()>, wrap: Wrap::If<(usize, &[u8]), ()>, input: &[u8],
459
    output: &mut [MaybeUninit<u8>],
460
) {
461
    let (col, end) = match Wrap::open(wrap) {
×
462
        If::Then((col, end)) => (col, end),
×
463
        If::Else(()) => return encode_pad::<Bit, Msb, Pad>(symbols, pad, input, output),
×
464
    };
465
    debug_assert_eq!(output.len(), encode_wrap_len::<Bit, Pad, Wrap>(wrap, input.len()));
×
466
    debug_assert_eq!(col % dec(Bit::VAL), 0);
×
467
    let bit = Bit::VAL;
×
468
    let col = col / dec(bit);
×
469
    let enc = col * enc(bit);
×
470
    let dec = col * dec(bit) + end.len();
×
471
    let olen = dec - end.len();
×
472
    let n = input.len() / enc;
×
473
    for i in 0 .. n {
×
474
        let input = unsafe { chunk_unchecked(input, enc, i) };
×
475
        let output = unsafe { chunk_mut_unchecked(output, dec, i) };
×
476
        encode_base::<Bit, Msb>(symbols, input, &mut output[.. olen]);
×
477
        unsafe { copy_from_slice(&mut output[olen ..], end) };
×
478
    }
479
    if input.len() > enc * n {
×
480
        let olen = dec * n + encode_pad_len::<Bit, Pad>(input.len() - enc * n);
×
481
        encode_pad::<Bit, Msb, Pad>(symbols, pad, &input[enc * n ..], &mut output[dec * n .. olen]);
×
482
        unsafe { copy_from_slice(&mut output[olen ..], end) };
×
483
    }
484
}
485

486
// Returns the longest valid input length and associated output length.
487
fn decode_wrap_len<Bit: BitWidth, Pad: Bool>(len: usize) -> (usize, usize) {
×
488
    let bit = Bit::VAL;
×
489
    if Pad::VAL {
×
490
        (floor(len, dec(bit)), len / dec(bit) * enc(bit))
×
491
    } else {
492
        let trail = bit * len % 8;
×
493
        (len - trail / bit, bit * len / 8)
×
494
    }
495
}
496

497
// Fails with Length if length is invalid. The error is the largest valid
498
// length.
499
fn decode_pad_len<Bit: BitWidth, Pad: Bool>(len: usize) -> Result<usize, DecodeError> {
×
500
    let (ilen, olen) = decode_wrap_len::<Bit, Pad>(len);
×
501
    check!(DecodeError { position: ilen, kind: DecodeKind::Length }, ilen == len);
×
502
    Ok(olen)
×
503
}
504

505
// Fails with Length if length is invalid. The error is the largest valid
506
// length.
507
fn decode_base_len<Bit: BitWidth>(len: usize) -> Result<usize, DecodeError> {
×
508
    decode_pad_len::<Bit, False>(len)
×
509
}
510

511
// Fails with Symbol if an input character does not translate to a symbol. The
512
// error is the lowest index of such character.
513
// Fails with Trailing if there are non-zero trailing bits.
514
fn decode_base_mut<Bit: BitWidth, Msb: Bool>(
515
    ctb: bool, values: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
516
) -> Result<usize, DecodePartial> {
517
    debug_assert_eq!(Ok(output.len()), decode_base_len::<Bit>(input.len()));
×
518
    let bit = Bit::VAL;
×
519
    let fail = |pos, kind| DecodePartial {
520
        read: pos / dec(bit) * dec(bit),
×
521
        written: pos / dec(bit) * enc(bit),
×
522
        error: DecodeError { position: pos, kind },
×
523
    };
524
    decode_mut::<Bit, Msb>(values, input, output).map_err(|pos| fail(pos, DecodeKind::Symbol))?;
×
525
    check_trail::<Bit, Msb>(ctb, values, input)
×
526
        .map_err(|()| fail(input.len() - 1, DecodeKind::Trailing))?;
×
527
    Ok(output.len())
×
528
}
529

530
// Fails with Symbol if an input character does not translate to a symbol. The
531
// error is the lowest index of such character.
532
// Fails with Padding if some padding length is invalid. The error is the index
533
// of the first padding character of the invalid padding.
534
// Fails with Trailing if there are non-zero trailing bits.
535
fn decode_pad_mut<Bit: BitWidth, Msb: Bool, Pad: Bool>(
536
    ctb: bool, values: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
537
) -> Result<usize, DecodePartial> {
538
    if !Pad::VAL {
×
539
        return decode_base_mut::<Bit, Msb>(ctb, values, input, output);
×
540
    }
541
    debug_assert_eq!(Ok(output.len()), decode_pad_len::<Bit, Pad>(input.len()));
×
542
    let bit = Bit::VAL;
×
543
    let enc = enc(bit);
×
544
    let dec = dec(bit);
×
545
    let mut inpos = 0;
×
546
    let mut outpos = 0;
×
547
    let mut outend = output.len();
×
548
    while inpos < input.len() {
×
549
        match decode_base_mut::<Bit, Msb>(
×
550
            ctb,
×
551
            values,
×
552
            &input[inpos ..],
×
553
            &mut output[outpos .. outend],
×
554
        ) {
555
            Ok(written) => {
×
556
                if cfg!(debug_assertions) {
557
                    inpos = input.len();
×
558
                }
559
                outpos += written;
×
560
                break;
×
561
            }
562
            Err(partial) => {
×
563
                inpos += partial.read;
×
564
                outpos += partial.written;
×
565
            }
566
        }
567
        let inlen = check_pad::<Bit>(values, &input[inpos .. inpos + dec]).map_err(|pos| {
×
568
            DecodePartial {
×
569
                read: inpos,
×
570
                written: outpos,
×
571
                error: DecodeError { position: inpos + pos, kind: DecodeKind::Padding },
×
572
            }
573
        })?;
574
        let outlen = decode_base_len::<Bit>(inlen).unwrap();
×
575
        let written = decode_base_mut::<Bit, Msb>(
576
            ctb,
×
577
            values,
×
578
            &input[inpos .. inpos + inlen],
×
579
            &mut output[outpos .. outpos + outlen],
×
580
        )
581
        .map_err(|partial| {
×
582
            debug_assert_eq!(partial.read, 0);
×
583
            debug_assert_eq!(partial.written, 0);
×
584
            DecodePartial {
×
585
                read: inpos,
×
586
                written: outpos,
×
587
                error: DecodeError {
×
588
                    position: inpos + partial.error.position,
×
589
                    kind: partial.error.kind,
×
590
                },
591
            }
592
        })?;
593
        debug_assert_eq!(written, outlen);
×
594
        inpos += dec;
×
595
        outpos += outlen;
×
596
        outend -= enc - outlen;
×
597
    }
598
    debug_assert_eq!(inpos, input.len());
×
599
    debug_assert_eq!(outpos, outend);
×
600
    Ok(outend)
×
601
}
602

603
fn skip_ignore(values: &[u8; 256], input: &[u8], mut inpos: usize) -> usize {
604
    while inpos < input.len() && values[input[inpos] as usize] == IGNORE {
605
        inpos += 1;
606
    }
607
    inpos
608
}
609

610
// Returns next input and output position.
611
// Fails with Symbol if an input character does not translate to a symbol. The
612
// error is the lowest index of such character.
613
// Fails with Padding if some padding length is invalid. The error is the index
614
// of the first padding character of the invalid padding.
615
// Fails with Trailing if there are non-zero trailing bits.
616
fn decode_wrap_block<Bit: BitWidth, Msb: Bool, Pad: Bool>(
617
    ctb: bool, values: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
618
) -> Result<(usize, usize), DecodeError> {
619
    let bit = Bit::VAL;
×
620
    let dec = dec(bit);
×
621
    let mut buf = [0u8; 8];
×
622
    let mut shift = [0usize; 8];
×
623
    let mut bufpos = 0;
×
624
    let mut inpos = 0;
×
625
    while bufpos < dec {
×
626
        inpos = skip_ignore(values, input, inpos);
×
627
        if inpos == input.len() {
×
628
            break;
×
629
        }
630
        shift[bufpos] = inpos;
×
631
        buf[bufpos] = input[inpos];
×
632
        bufpos += 1;
×
633
        inpos += 1;
×
634
    }
635
    let olen = decode_pad_len::<Bit, Pad>(bufpos).map_err(|mut e| {
×
636
        e.position = shift[e.position];
×
637
        e
×
638
    })?;
639
    let written =
×
640
        decode_pad_mut::<Bit, Msb, Pad>(ctb, values, &buf[.. bufpos], &mut output[.. olen])
×
641
            .map_err(|partial| {
×
642
                debug_assert_eq!(partial.read, 0);
×
643
                debug_assert_eq!(partial.written, 0);
×
644
                DecodeError { position: shift[partial.error.position], kind: partial.error.kind }
×
645
            })?;
646
    Ok((inpos, written))
×
647
}
648

649
// Fails with Symbol if an input character does not translate to a symbol. The
650
// error is the lowest index of such character.
651
// Fails with Padding if some padding length is invalid. The error is the index
652
// of the first padding character of the invalid padding.
653
// Fails with Trailing if there are non-zero trailing bits.
654
// Fails with Length if input length (without ignored characters) is invalid.
655
fn decode_wrap_mut<Bit: BitWidth, Msb: Bool, Pad: Bool, Ignore: Bool>(
656
    ctb: bool, values: &[u8; 256], input: &[u8], output: &mut [MaybeUninit<u8>],
657
) -> Result<usize, DecodePartial> {
658
    if !Ignore::VAL {
×
659
        return decode_pad_mut::<Bit, Msb, Pad>(ctb, values, input, output);
×
660
    }
661
    debug_assert_eq!(output.len(), decode_wrap_len::<Bit, Pad>(input.len()).1);
×
662
    let mut inpos = 0;
×
663
    let mut outpos = 0;
×
664
    while inpos < input.len() {
×
665
        let (inlen, outlen) = decode_wrap_len::<Bit, Pad>(input.len() - inpos);
×
666
        match decode_pad_mut::<Bit, Msb, Pad>(
×
667
            ctb,
×
668
            values,
×
669
            &input[inpos .. inpos + inlen],
×
670
            &mut output[outpos .. outpos + outlen],
×
671
        ) {
672
            Ok(written) => {
×
673
                inpos += inlen;
×
674
                outpos += written;
×
675
                break;
×
676
            }
677
            Err(partial) => {
×
678
                inpos += partial.read;
×
679
                outpos += partial.written;
×
680
            }
681
        }
682
        let (ipos, opos) = decode_wrap_block::<Bit, Msb, Pad>(
683
            ctb,
×
684
            values,
×
685
            &input[inpos ..],
×
686
            &mut output[outpos ..],
×
687
        )
688
        .map_err(|mut error| {
×
689
            error.position += inpos;
×
690
            DecodePartial { read: inpos, written: outpos, error }
×
691
        })?;
692
        inpos += ipos;
×
693
        outpos += opos;
×
694
    }
695
    let inpos = skip_ignore(values, input, inpos);
×
696
    if inpos == input.len() {
×
697
        Ok(outpos)
×
698
    } else {
699
        Err(DecodePartial {
×
700
            read: inpos,
×
701
            written: outpos,
×
702
            error: DecodeError { position: inpos, kind: DecodeKind::Length },
×
703
        })
704
    }
705
}
706

707
/// Error converting from a dynamic encoding to a static one.
708
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
709
pub enum ConvertError {
710
    /// Different bit-width.
711
    BitWidth,
712

713
    /// Different bit-order.
714
    BitOrder,
715

716
    /// Different padding.
717
    Padding,
718

719
    /// Different wrap.
720
    Wrap,
721

722
    /// Different ignore.
723
    Ignore,
724
}
725

726
/// Base-conversion encoding.
727
///
728
/// See [`Specification`] for technical details or how to define a new one.
729
#[derive(Debug, Clone, PartialEq, Eq)]
730
#[repr(transparent)]
731
pub struct Encoding<Bit: BitWidth, Msb: Bool, Pad: Bool, Wrap: Bool, Ignore: Bool> {
732
    // The config match the fields in data. In particular, we have the following properties:
733
    // - If Bit is Bit1, Bit2, or Bit4 then Pad is False.
734
    // - If Wrap is True, then Ignore is True.
735
    data: InternalEncoding,
736
    _type: PhantomData<(Bit, Msb, Pad, Wrap, Ignore)>,
737
}
738

739
/// Base-conversion encoding
740
///
741
/// See [`Specification`] for technical details or how to define a new one.
742
// Required fields:
743
//   0 - 256 (256) symbols
744
// 256 - 512 (256) values
745
// 512 - 513 (  1) padding
746
// 513 - 514 (  1) reserved(3),ctb(1),msb(1),bit(3)
747
// Optional fields:
748
// 514 - 515 (  1) width
749
// 515 -   * (  N) separator
750
// Invariants:
751
// - symbols is 2^bit unique characters repeated 2^(8-bit) times
752
// - values[128 ..] are INVALID
753
// - values[0 .. 128] are either INVALID, IGNORE, PADDING, or < 2^bit
754
// - padding is either < 128 or INVALID
755
// - values[padding] is PADDING if padding < 128
756
// - values and symbols are inverse
757
// - ctb is true if 8 % bit == 0
758
// - width is present if there is x such that values[x] is IGNORE
759
// - width % dec(bit) == 0
760
// - for all x in separator values[x] is IGNORE
761
#[derive(Debug, Clone, PartialEq, Eq)]
762
#[repr(transparent)]
763
pub struct DynEncoding(InternalEncoding);
764

765
#[cfg(feature = "alloc")]
766
type InternalEncoding = Cow<'static, [u8]>;
767

768
#[cfg(not(feature = "alloc"))]
769
type InternalEncoding = &'static [u8];
770

771
impl<Bit: BitWidth, Msb: Bool, Pad: Bool, Wrap: Bool, Ignore: Bool>
772
    Encoding<Bit, Msb, Pad, Wrap, Ignore>
773
{
774
    fn sym(&self) -> &[u8; 256] {
×
775
        self.data[0 .. 256].try_into().unwrap()
×
776
    }
777

778
    fn val(&self) -> &[u8; 256] {
×
779
        self.data[256 .. 512].try_into().unwrap()
×
780
    }
781

782
    fn pad(&self) -> Pad::If<u8, ()> {
×
783
        Pad::make(|| self.data[512], || ())
×
784
    }
785

786
    fn ctb(&self) -> bool {
×
787
        self.data[513] & 0x10 != 0
×
788
    }
789

790
    fn wrap(&self) -> Wrap::If<(usize, &[u8]), ()> {
×
791
        Wrap::make(|| (self.data[514] as usize, &self.data[515 ..]), || ())
×
792
    }
793

794
    fn has_ignore(&self) -> bool {
×
795
        self.data.len() >= 515
×
796
    }
797

798
    /// Minimum number of input and output blocks when encoding.
799
    fn block_len(&self) -> (usize, usize) {
×
800
        let bit = Bit::VAL;
×
801
        match Wrap::open(self.wrap()) {
×
802
            If::Then((col, end)) => (col / dec(bit) * enc(bit), col + end.len()),
×
803
            If::Else(()) => (enc(bit), dec(bit)),
×
804
        }
805
    }
806

807
    /// Returns the encoded length of an input of length `len`.
808
    ///
809
    /// See [`Self::encode_mut()`] for when to use it.
810
    #[must_use]
811
    pub fn encode_len(&self, len: usize) -> usize {
×
812
        encode_wrap_len::<Bit, Pad, Wrap>(self.wrap(), len)
×
813
    }
814

815
    /// Encodes `input` in `output`.
816
    ///
817
    /// # Panics
818
    ///
819
    /// Panics if the `output` length does not match the result of [`Self::encode_len()`] for the
820
    /// `input` length.
821
    pub fn encode_mut_uninit<'a>(
822
        &self, input: &[u8], output: &'a mut [MaybeUninit<u8>],
823
    ) -> &'a mut [u8] {
824
        assert_eq!(output.len(), self.encode_len(input.len()));
×
825
        encode_wrap_mut::<Bit, Msb, Pad, Wrap>(self.sym(), self.pad(), self.wrap(), input, output);
×
826
        unsafe { slice_assume_init_mut(output) }
×
827
    }
828

829
    /// Encodes `input` in `output`.
830
    ///
831
    /// # Panics
832
    ///
833
    /// Panics if the `output` length does not match the result of [`Self::encode_len()`] for the
834
    /// `input` length.
835
    pub fn encode_mut(&self, input: &[u8], output: &mut [u8]) {
×
836
        let _ = self.encode_mut_uninit(input, unsafe { slice_uninit_mut(output) });
×
837
    }
838

839
    /// Appends the encoding of `input` to `output`.
840
    #[cfg(feature = "alloc")]
841
    pub fn encode_append(&self, input: &[u8], output: &mut String) {
×
842
        let output = unsafe { output.as_mut_vec() };
×
843
        let output_len = output.len();
×
844
        let len = self.encode_len(input.len());
×
845
        let actual_len = self.encode_mut_uninit(input, reserve_spare(output, len)).len();
×
846
        debug_assert_eq!(actual_len, len);
×
847
        unsafe { output.set_len(output_len + len) };
×
848
    }
849

850
    // /// Returns an object to encode a fragmented input and append it to `output`.
851
    // ///
852
    // /// See the documentation of [`Encoder`] for more details and examples.
853
    // #[cfg(feature = "alloc")]
854
    // pub fn new_encoder<'a>(
855
    //     &'a self, output: &'a mut String,
856
    // ) -> Encoder<'a, Bit, Msb, Pad, Wrap, Ignore> {
857
    //     Encoder::new(self, output)
858
    // }
859

860
    /// Writes the encoding of `input` to `output` using a temporary `buffer`.
861
    ///
862
    /// # Panics
863
    ///
864
    /// Panics if the buffer is shorter than 510 bytes.
865
    ///
866
    /// # Errors
867
    ///
868
    /// Returns an error when writing to the output fails.
869
    pub fn encode_write_buffer_uninit(
870
        &self, input: &[u8], output: &mut impl core::fmt::Write, buffer: &mut [MaybeUninit<u8>],
871
    ) -> core::fmt::Result {
872
        assert!(510 <= buffer.len());
×
873
        let (enc, dec) = self.block_len();
×
874
        for input in input.chunks(buffer.len() / dec * enc) {
×
875
            let buffer = &mut buffer[.. self.encode_len(input.len())];
×
876
            let buffer = self.encode_mut_uninit(input, buffer);
×
877
            output.write_str(unsafe { core::str::from_utf8_unchecked(buffer) })?;
×
878
        }
879
        Ok(())
×
880
    }
881

882
    /// Writes the encoding of `input` to `output` using a temporary `buffer`.
883
    ///
884
    /// # Panics
885
    ///
886
    /// Panics if the buffer is shorter than 510 bytes.
887
    ///
888
    /// # Errors
889
    ///
890
    /// Returns an error when writing to the output fails.
891
    pub fn encode_write_buffer(
892
        &self, input: &[u8], output: &mut impl core::fmt::Write, buffer: &mut [u8],
893
    ) -> core::fmt::Result {
894
        self.encode_write_buffer_uninit(input, output, unsafe { slice_uninit_mut(buffer) })
×
895
    }
896

897
    /// Writes the encoding of `input` to `output`.
898
    ///
899
    /// This allocates a buffer of 1024 bytes on the stack. If you want to control the buffer size
900
    /// and location, use [`Self::encode_write_buffer()`] instead.
901
    ///
902
    /// # Errors
903
    ///
904
    /// Returns an error when writing to the output fails.
905
    pub fn encode_write(
906
        &self, input: &[u8], output: &mut impl core::fmt::Write,
907
    ) -> core::fmt::Result {
908
        self.encode_write_buffer(input, output, &mut [0; 1024])
×
909
    }
910

911
    /// Returns encoded `input`.
912
    #[cfg(feature = "alloc")]
913
    #[must_use]
914
    pub fn encode(&self, input: &[u8]) -> String {
×
915
        let mut output = Vec::new();
×
916
        let len = self.encode_len(input.len());
×
917
        let actual_len = self.encode_mut_uninit(input, reserve_spare(&mut output, len)).len();
×
918
        debug_assert_eq!(actual_len, len);
×
919
        unsafe { output.set_len(len) };
×
920
        unsafe { String::from_utf8_unchecked(output) }
×
921
    }
922

923
    /// Returns the decoded length of an input of length `len`.
924
    ///
925
    /// See [`Self::decode_mut()`] for when to use it.
926
    ///
927
    /// # Errors
928
    ///
929
    /// Returns an error if `len` is invalid. The error [kind][DecodeError::kind] is
930
    /// [`DecodeKind::Length`] and the error [position][DecodeError::position] is the greatest valid
931
    /// input length.
932
    pub fn decode_len(&self, len: usize) -> Result<usize, DecodeError> {
×
933
        let (ilen, olen) = decode_wrap_len::<Bit, Pad>(len);
×
934
        check!(
×
935
            DecodeError { position: ilen, kind: DecodeKind::Length },
×
936
            self.has_ignore() || len == ilen
×
937
        );
938
        Ok(olen)
×
939
    }
940

941
    /// Decodes `input` in `output`.
942
    ///
943
    /// Returns the decoded output. Its length may be smaller than the output length if the input
944
    /// contained padding or ignored characters. The output bytes after the returned length are not
945
    /// initialized and should not be read.
946
    ///
947
    /// # Panics
948
    ///
949
    /// Panics if the `output` length does not match the result of [`Self::decode_len()`] for the
950
    /// `input` length. Also panics if `decode_len` fails for the `input` length.
951
    ///
952
    /// # Errors
953
    ///
954
    /// Returns an error if `input` is invalid. See [`Self::decode_mut()`] for more details.
955
    pub fn decode_mut_uninit<'a>(
956
        &self, input: &[u8], output: &'a mut [MaybeUninit<u8>],
957
    ) -> Result<&'a mut [u8], DecodePartial> {
958
        assert_eq!(Ok(output.len()), self.decode_len(input.len()));
×
959
        let len = decode_wrap_mut::<Bit, Msb, Pad, Ignore>(self.ctb(), self.val(), input, output)?;
×
960
        Ok(unsafe { slice_assume_init_mut(&mut output[.. len]) })
×
961
    }
962

963
    /// Decodes `input` in `output`.
964
    ///
965
    /// Returns the length of the decoded output. This length may be smaller than the output length
966
    /// if the input contained padding or ignored characters. The output bytes after the returned
967
    /// length are not initialized and should not be read.
968
    ///
969
    /// # Panics
970
    ///
971
    /// Panics if the `output` length does not match the result of [`Self::decode_len()`] for the
972
    /// `input` length. Also panics if `decode_len` fails for the `input` length.
973
    ///
974
    /// # Errors
975
    ///
976
    /// Returns an error if `input` is invalid. See [`Self::decode()`] for more details. The are two
977
    /// differences though:
978
    ///
979
    /// - [`DecodeKind::Length`] may be returned only if the encoding allows ignored characters,
980
    ///   because otherwise this is already checked by [`Self::decode_len()`].
981
    /// - The [`DecodePartial::read`] first bytes of the input have been successfully decoded to the
982
    ///   [`DecodePartial::written`] first bytes of the output.
983
    pub fn decode_mut(&self, input: &[u8], output: &mut [u8]) -> Result<usize, DecodePartial> {
×
984
        Ok(self.decode_mut_uninit(input, unsafe { slice_uninit_mut(output) })?.len())
×
985
    }
986

987
    /// Returns decoded `input`.
988
    ///
989
    /// # Errors
990
    ///
991
    /// Returns an error if `input` is invalid. The error kind can be:
992
    ///
993
    /// - [`DecodeKind::Length`] if the input length is invalid. The [position] is the greatest
994
    ///   valid input length.
995
    /// - [`DecodeKind::Symbol`] if the input contains an invalid character. The [position] is the
996
    ///   first invalid character.
997
    /// - [`DecodeKind::Trailing`] if the input has non-zero trailing bits. This is only possible if
998
    ///   the encoding checks trailing bits. The [position] is the first character containing
999
    ///   non-zero trailing bits.
1000
    /// - [`DecodeKind::Padding`] if the input has an invalid padding length. This is only possible
1001
    ///   if the encoding uses padding. The [position] is the first padding character of the first
1002
    ///   padding of invalid length.
1003
    ///
1004
    /// [position]: DecodeError::position
1005
    #[cfg(feature = "alloc")]
1006
    pub fn decode(&self, input: &[u8]) -> Result<Vec<u8>, DecodeError> {
×
1007
        let max_len = self.decode_len(input.len())?;
×
1008
        let mut output = Vec::new();
×
1009
        let len = self
×
1010
            .decode_mut_uninit(input, reserve_spare(&mut output, max_len))
×
1011
            .map_err(|partial| partial.error)?
×
1012
            .len();
1013
        unsafe { output.set_len(len) };
×
1014
        Ok(output)
×
1015
    }
1016

1017
    /// TODO
1018
    #[cfg(feature = "alloc")]
1019
    #[must_use]
1020
    pub fn specification(&self) -> Specification {
×
1021
        DynEncoding::specification(self.into())
×
1022
    }
1023

1024
    /// TODO
1025
    #[must_use]
1026
    pub fn as_dyn(&self) -> &DynEncoding {
×
1027
        self.into()
×
1028
    }
1029

1030
    #[doc(hidden)]
1031
    #[must_use]
1032
    pub const unsafe fn new_unchecked(data: &'static [u8]) -> Self {
×
1033
        #[cfg(feature = "alloc")]
1034
        let data = Cow::Borrowed(data);
×
1035
        Encoding { data, _type: PhantomData }
1036
    }
1037

1038
    fn check_compatible(base: &DynEncoding) -> Result<(), ConvertError> {
×
1039
        check!(ConvertError::BitWidth, base.bit() == Bit::VAL);
×
1040
        check!(ConvertError::BitOrder, base.msb() == Msb::VAL);
×
1041
        check!(ConvertError::Padding, base.pad().is_some() == Pad::VAL);
×
1042
        check!(ConvertError::Wrap, base.wrap().is_some() == Wrap::VAL);
×
1043
        check!(ConvertError::Ignore, base.has_ignore() == Ignore::VAL);
×
1044
        Ok(())
×
1045
    }
1046
}
1047

1048
impl DynEncoding {
1049
    fn sym(&self) -> &[u8; 256] {
1050
        self.0[0 .. 256].try_into().unwrap()
1051
    }
1052

1053
    fn val(&self) -> &[u8; 256] {
1054
        self.0[256 .. 512].try_into().unwrap()
1055
    }
1056

1057
    fn pad(&self) -> Option<u8> {
1058
        if self.0[512] < 128 { Some(self.0[512]) } else { None }
1059
    }
1060

1061
    fn ctb(&self) -> bool {
1062
        self.0[513] & 0x10 != 0
1063
    }
1064

1065
    fn msb(&self) -> bool {
1066
        self.0[513] & 0x8 != 0
1067
    }
1068

1069
    fn bit(&self) -> usize {
1070
        (self.0[513] & 0x7) as usize
1071
    }
1072

1073
    /// Minimum number of input and output blocks when encoding
1074
    fn block_len(&self) -> (usize, usize) {
1075
        let bit = self.bit();
1076
        match self.wrap() {
1077
            Some((col, end)) => (col / dec(bit) * enc(bit), col + end.len()),
1078
            None => (enc(bit), dec(bit)),
1079
        }
1080
    }
1081

1082
    fn wrap(&self) -> Option<(usize, &[u8])> {
1083
        if self.0.len() <= 515 {
1084
            return None;
1085
        }
1086
        Some((self.0[514] as usize, &self.0[515 ..]))
1087
    }
1088

1089
    fn has_ignore(&self) -> bool {
1090
        self.0.len() >= 515
1091
    }
1092

1093
    /// Returns the encoded length of an input of length `len`
1094
    ///
1095
    /// See [`encode_mut`] for when to use it.
1096
    ///
1097
    /// [`encode_mut`]: struct.Encoding.html#method.encode_mut
1098
    #[must_use]
1099
    pub fn encode_len(&self, len: usize) -> usize {
1100
        dispatch!(self.encode_len(len))
1101
    }
1102

1103
    /// Encodes `input` in `output`
1104
    ///
1105
    /// # Panics
1106
    ///
1107
    /// Panics if the `output` length does not match the result of [`encode_len`] for the `input`
1108
    /// length.
1109
    ///
1110
    /// # Examples
1111
    ///
1112
    /// ```rust
1113
    /// use data_encoding_v3::BASE64;
1114
    /// # let mut buffer = vec![0; 100];
1115
    /// let input = b"Hello world";
1116
    /// let output = &mut buffer[0 .. BASE64.encode_len(input.len())];
1117
    /// BASE64.encode_mut(input, output);
1118
    /// assert_eq!(output, b"SGVsbG8gd29ybGQ=");
1119
    /// ```
1120
    ///
1121
    /// [`encode_len`]: struct.Encoding.html#method.encode_len
1122
    #[allow(clippy::cognitive_complexity)]
1123
    pub fn encode_mut(&self, input: &[u8], output: &mut [u8]) {
1124
        dispatch!(self.encode_mut(input, output))
1125
    }
1126

1127
    /// Appends the encoding of `input` to `output`
1128
    ///
1129
    /// # Examples
1130
    ///
1131
    /// ```rust
1132
    /// use data_encoding_v3::BASE64;
1133
    /// # let mut buffer = vec![0; 100];
1134
    /// let input = b"Hello world";
1135
    /// let mut output = "Result: ".to_string();
1136
    /// BASE64.encode_append(input, &mut output);
1137
    /// assert_eq!(output, "Result: SGVsbG8gd29ybGQ=");
1138
    /// ```
1139
    #[cfg(feature = "alloc")]
1140
    pub fn encode_append(&self, input: &[u8], output: &mut String) {
1141
        let output = unsafe { output.as_mut_vec() };
1142
        let output_len = output.len();
1143
        output.resize(output_len + self.encode_len(input.len()), 0u8);
1144
        self.encode_mut(input, &mut output[output_len ..]);
1145
    }
1146

1147
    /// Writes the encoding of `input` to `output`
1148
    ///
1149
    /// This allocates a buffer of 1024 bytes on the stack. If you want to control the buffer size
1150
    /// and location, use [`Encoding::encode_write_buffer()`] instead.
1151
    ///
1152
    /// # Errors
1153
    ///
1154
    /// Returns an error when writing to the output fails.
1155
    pub fn encode_write(
1156
        &self, input: &[u8], output: &mut impl core::fmt::Write,
1157
    ) -> core::fmt::Result {
1158
        self.encode_write_buffer(input, output, &mut [0; 1024])
1159
    }
1160

1161
    /// Writes the encoding of `input` to `output` using a temporary `buffer`
1162
    ///
1163
    /// # Panics
1164
    ///
1165
    /// Panics if the buffer is shorter than 510 bytes.
1166
    ///
1167
    /// # Errors
1168
    ///
1169
    /// Returns an error when writing to the output fails.
1170
    pub fn encode_write_buffer(
1171
        &self, input: &[u8], output: &mut impl core::fmt::Write, buffer: &mut [u8],
1172
    ) -> core::fmt::Result {
1173
        assert!(510 <= buffer.len());
1174
        let (enc, dec) = self.block_len();
1175
        for input in input.chunks(buffer.len() / dec * enc) {
1176
            let buffer = &mut buffer[.. self.encode_len(input.len())];
1177
            self.encode_mut(input, buffer);
1178
            output.write_str(unsafe { core::str::from_utf8_unchecked(buffer) })?;
1179
        }
1180
        Ok(())
1181
    }
1182

1183
    /// Returns encoded `input`
1184
    ///
1185
    /// # Examples
1186
    ///
1187
    /// ```rust
1188
    /// use data_encoding_v3::BASE64;
1189
    /// assert_eq!(BASE64.encode(b"Hello world"), "SGVsbG8gd29ybGQ=");
1190
    /// ```
1191
    #[cfg(feature = "alloc")]
1192
    #[must_use]
1193
    pub fn encode(&self, input: &[u8]) -> String {
1194
        let mut output = vec![0u8; self.encode_len(input.len())];
1195
        self.encode_mut(input, &mut output);
1196
        unsafe { String::from_utf8_unchecked(output) }
1197
    }
1198

1199
    /// Returns the maximum decoded length of an input of length `len`
1200
    ///
1201
    /// See [`decode_mut`] for when to use it. In particular, the actual decoded length might be
1202
    /// smaller if the actual input contains padding or ignored characters.
1203
    ///
1204
    /// # Errors
1205
    ///
1206
    /// Returns an error if `len` is invalid. The error kind is [`Length`] and the [position] is the
1207
    /// greatest valid input length.
1208
    ///
1209
    /// [`decode_mut`]: struct.Encoding.html#method.decode_mut
1210
    /// [`Length`]: enum.DecodeKind.html#variant.Length
1211
    /// [position]: struct.DecodeError.html#structfield.position
1212
    pub fn decode_len(&self, len: usize) -> Result<usize, DecodeError> {
1213
        dispatch!(self.decode_len(len))
1214
    }
1215

1216
    /// Decodes `input` in `output`
1217
    ///
1218
    /// Returns the length of the decoded output. This length may be smaller than the output length
1219
    /// if the input contained padding or ignored characters. The output bytes after the returned
1220
    /// length are not initialized and should not be read.
1221
    ///
1222
    /// # Panics
1223
    ///
1224
    /// Panics if the `output` length does not match the result of [`decode_len`] for the `input`
1225
    /// length. Also panics if `decode_len` fails for the `input` length.
1226
    ///
1227
    /// # Errors
1228
    ///
1229
    /// Returns an error if `input` is invalid. See [`decode`] for more details. The are two
1230
    /// differences though:
1231
    ///
1232
    /// - [`Length`] may be returned only if the encoding allows ignored characters, because
1233
    ///   otherwise this is already checked by [`decode_len`].
1234
    /// - The [`read`] first bytes of the input have been successfully decoded to the [`written`]
1235
    ///   first bytes of the output.
1236
    ///
1237
    /// # Examples
1238
    ///
1239
    /// ```rust
1240
    /// use data_encoding_v3::BASE64;
1241
    /// # let mut buffer = vec![0; 100];
1242
    /// let input = b"SGVsbA==byB3b3JsZA==";
1243
    /// let output = &mut buffer[0 .. BASE64.decode_len(input.len()).unwrap()];
1244
    /// let len = BASE64.decode_mut(input, output).unwrap();
1245
    /// assert_eq!(&output[0 .. len], b"Hello world");
1246
    /// ```
1247
    ///
1248
    /// [`decode_len`]: struct.Encoding.html#method.decode_len
1249
    /// [`decode`]: struct.Encoding.html#method.decode
1250
    /// [`Length`]: enum.DecodeKind.html#variant.Length
1251
    /// [`read`]: struct.DecodePartial.html#structfield.read
1252
    /// [`written`]: struct.DecodePartial.html#structfield.written
1253
    #[allow(clippy::cognitive_complexity)]
1254
    pub fn decode_mut(&self, input: &[u8], output: &mut [u8]) -> Result<usize, DecodePartial> {
1255
        dispatch!(self.decode_mut(input, output))
1256
    }
1257

1258
    /// Returns decoded `input`
1259
    ///
1260
    /// # Errors
1261
    ///
1262
    /// Returns an error if `input` is invalid. The error kind can be:
1263
    ///
1264
    /// - [`Length`] if the input length is invalid. The [position] is the greatest valid input
1265
    ///   length.
1266
    /// - [`Symbol`] if the input contains an invalid character. The [position] is the first invalid
1267
    ///   character.
1268
    /// - [`Trailing`] if the input has non-zero trailing bits. This is only possible if the
1269
    ///   encoding checks trailing bits. The [position] is the first character containing non-zero
1270
    ///   trailing bits.
1271
    /// - [`Padding`] if the input has an invalid padding length. This is only possible if the
1272
    ///   encoding uses padding. The [position] is the first padding character of the first padding
1273
    ///   of invalid length.
1274
    ///
1275
    /// # Examples
1276
    ///
1277
    /// ```rust
1278
    /// use data_encoding_v3::BASE64;
1279
    /// assert_eq!(BASE64.decode(b"SGVsbA==byB3b3JsZA==").unwrap(), b"Hello world");
1280
    /// ```
1281
    ///
1282
    /// [`Length`]: enum.DecodeKind.html#variant.Length
1283
    /// [`Symbol`]: enum.DecodeKind.html#variant.Symbol
1284
    /// [`Trailing`]: enum.DecodeKind.html#variant.Trailing
1285
    /// [`Padding`]: enum.DecodeKind.html#variant.Padding
1286
    /// [position]: struct.DecodeError.html#structfield.position
1287
    #[cfg(feature = "alloc")]
1288
    pub fn decode(&self, input: &[u8]) -> Result<Vec<u8>, DecodeError> {
1289
        let mut output = vec![0u8; self.decode_len(input.len())?];
1290
        let len = self.decode_mut(input, &mut output).map_err(|partial| partial.error)?;
1291
        output.truncate(len);
1292
        Ok(output)
1293
    }
1294

1295
    /// Returns the bit-width
1296
    #[must_use]
1297
    pub fn bit_width(&self) -> usize {
1298
        self.bit()
1299
    }
1300

1301
    /// Returns whether the encoding is canonical
1302
    ///
1303
    /// An encoding is not canonical if one of the following conditions holds:
1304
    ///
1305
    /// - trailing bits are not checked
1306
    /// - padding is used
1307
    /// - characters are ignored
1308
    /// - characters are translated
1309
    #[must_use]
1310
    pub fn is_canonical(&self) -> bool {
1311
        if !self.ctb() {
1312
            return false;
1313
        }
1314
        let bit = self.bit();
1315
        let sym = self.sym();
1316
        let val = self.val();
1317
        for i in 0 .. 256 {
1318
            if val[i] == INVALID {
1319
                continue;
1320
            }
1321
            if val[i] >= 1 << bit {
1322
                return false;
1323
            }
1324
            if sym[val[i] as usize] as usize != i {
1325
                return false;
1326
            }
1327
        }
1328
        true
1329
    }
1330

1331
    /// Returns the encoding specification
1332
    #[allow(clippy::missing_panics_doc)] // no panic
1333
    #[cfg(feature = "alloc")]
1334
    #[must_use]
1335
    pub fn specification(&self) -> Specification {
1336
        let mut specification = Specification::new();
1337
        specification
1338
            .symbols
1339
            .push_str(core::str::from_utf8(&self.sym()[0 .. 1 << self.bit()]).unwrap());
1340
        specification.bit_order =
1341
            if self.msb() { MostSignificantFirst } else { LeastSignificantFirst };
1342
        specification.check_trailing_bits = self.ctb();
1343
        if let Some(pad) = self.pad() {
1344
            specification.padding = Some(pad as char);
1345
        }
1346
        for i in 0 .. 128u8 {
1347
            if self.val()[i as usize] != IGNORE {
1348
                continue;
1349
            }
1350
            specification.ignore.push(i as char);
1351
        }
1352
        if let Some((col, end)) = self.wrap() {
1353
            specification.wrap.width = col;
1354
            specification.wrap.separator = core::str::from_utf8(end).unwrap().to_owned();
1355
        }
1356
        for i in 0 .. 128u8 {
1357
            let canonical = if self.val()[i as usize] < 1 << self.bit() {
1358
                self.sym()[self.val()[i as usize] as usize]
1359
            } else if self.val()[i as usize] == PADDING {
1360
                self.pad().unwrap()
1361
            } else {
1362
                continue;
1363
            };
1364
            if i == canonical {
1365
                continue;
1366
            }
1367
            specification.translate.from.push(i as char);
1368
            specification.translate.to.push(canonical as char);
1369
        }
1370
        specification
1371
    }
1372

1373
    #[doc(hidden)]
1374
    #[must_use]
1375
    pub const unsafe fn internal_new(implementation: &'static [u8]) -> DynEncoding {
1376
        #[cfg(feature = "alloc")]
1377
        let encoding = DynEncoding(Cow::Borrowed(implementation));
1378
        #[cfg(not(feature = "alloc"))]
1379
        let encoding = DynEncoding(implementation);
1380
        encoding
1381
    }
1382

1383
    #[doc(hidden)]
1384
    #[must_use]
1385
    pub fn internal_implementation(&self) -> &[u8] {
1386
        &self.0
1387
    }
1388
}
1389

1390
impl<Bit: BitWidth, Msb: Bool, Pad: Bool, Wrap: Bool, Ignore: Bool> TryFrom<DynEncoding>
1391
    for Encoding<Bit, Msb, Pad, Wrap, Ignore>
1392
{
1393
    type Error = ConvertError;
1394

1395
    fn try_from(base: DynEncoding) -> Result<Self, Self::Error> {
×
1396
        Encoding::<Bit, Msb, Pad, Wrap, Ignore>::check_compatible(&base)?;
×
1397
        Ok(Encoding { data: base.0, _type: PhantomData })
×
1398
    }
1399
}
1400

1401
impl<Bit: BitWidth, Msb: Bool, Pad: Bool, Wrap: Bool, Ignore: Bool>
1402
    From<Encoding<Bit, Msb, Pad, Wrap, Ignore>> for DynEncoding
1403
{
1404
    fn from(base: Encoding<Bit, Msb, Pad, Wrap, Ignore>) -> Self {
×
1405
        DynEncoding(base.data)
×
1406
    }
1407
}
1408

1409
impl<'a, Bit: BitWidth, Msb: Bool, Pad: Bool, Wrap: Bool, Ignore: Bool> TryFrom<&'a DynEncoding>
1410
    for &'a Encoding<Bit, Msb, Pad, Wrap, Ignore>
1411
{
1412
    type Error = ConvertError;
1413

1414
    fn try_from(base: &'a DynEncoding) -> Result<Self, Self::Error> {
×
1415
        Encoding::<Bit, Msb, Pad, Wrap, Ignore>::check_compatible(base)?;
×
1416
        Ok(unsafe { cast(base) })
×
1417
    }
1418
}
1419

1420
impl<'a, Bit: BitWidth, Msb: Bool, Pad: Bool, Wrap: Bool, Ignore: Bool>
1421
    From<&'a Encoding<Bit, Msb, Pad, Wrap, Ignore>> for &'a DynEncoding
1422
{
1423
    fn from(base: &'a Encoding<Bit, Msb, Pad, Wrap, Ignore>) -> Self {
×
1424
        unsafe { &*core::ptr::from_ref(base).cast::<DynEncoding>() }
×
1425
    }
1426
}
1427

1428
/// Order in which bits are read from a byte
1429
///
1430
/// The base-conversion encoding is always little-endian. This means that the least significant
1431
/// **byte** is always first. However, we can still choose whether, within a byte, this is the most
1432
/// significant or the least significant **bit** that is first. If the terminology is confusing,
1433
/// testing on an asymmetrical example should be enough to choose the correct value.
1434
///
1435
/// # Examples
1436
///
1437
/// In the following example, we can see that a base with the `MostSignificantFirst` bit-order has
1438
/// the most significant bit first in the encoded output. In particular, the output is in the same
1439
/// order as the bits in the byte. The opposite happens with the `LeastSignificantFirst` bit-order.
1440
/// The least significant bit is first and the output is in the reverse order.
1441
///
1442
/// ```rust
1443
/// use data_encoding_v3::{BitOrder, Specification};
1444
/// let mut spec = Specification::new();
1445
/// spec.symbols.push_str("01");
1446
/// spec.bit_order = BitOrder::MostSignificantFirst;  // default
1447
/// let msb = spec.encoding().unwrap();
1448
/// spec.bit_order = BitOrder::LeastSignificantFirst;
1449
/// let lsb = spec.encoding().unwrap();
1450
/// assert_eq!(msb.encode(&[0b01010011]), "01010011");
1451
/// assert_eq!(lsb.encode(&[0b01010011]), "11001010");
1452
/// ```
1453
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1454
#[cfg(feature = "alloc")]
1455
pub enum BitOrder {
1456
    /// Most significant bit first
1457
    ///
1458
    /// This is the most common and most intuitive bit-order. In particular, this is the bit-order
1459
    /// used by [RFC4648] and thus the usual hexadecimal, base64, base32, base64url, and base32hex
1460
    /// encodings. This is the default bit-order when [specifying](struct.Specification.html) a
1461
    /// base.
1462
    ///
1463
    /// [RFC4648]: https://tools.ietf.org/html/rfc4648
1464
    MostSignificantFirst,
1465

1466
    /// Least significant bit first
1467
    ///
1468
    /// # Examples
1469
    ///
1470
    /// DNSCurve [base32] uses least significant bit first:
1471
    ///
1472
    /// ```rust
1473
    /// use data_encoding_v3::BASE32_DNSCURVE;
1474
    /// assert_eq!(BASE32_DNSCURVE.encode(&[0x64, 0x88]), "4321");
1475
    /// assert_eq!(BASE32_DNSCURVE.decode(b"4321").unwrap(), vec![0x64, 0x88]);
1476
    /// ```
1477
    ///
1478
    /// [base32]: constant.BASE32_DNSCURVE.html
1479
    LeastSignificantFirst,
1480
}
1481
#[cfg(feature = "alloc")]
1482
use crate::BitOrder::*;
1483

1484
/// How to translate characters when decoding
1485
///
1486
/// The order matters. The first character of the `from` field is translated to the first character
1487
/// of the `to` field. The second to the second. Etc.
1488
///
1489
/// See [Specification](struct.Specification.html) for more information.
1490
#[derive(Debug, Clone)]
1491
#[cfg(feature = "alloc")]
1492
pub struct Translate {
1493
    /// Characters to translate from
1494
    pub from: String,
1495

1496
    /// Characters to translate to
1497
    pub to: String,
1498
}
1499

1500
/// How to wrap the output when encoding
1501
///
1502
/// See [Specification](struct.Specification.html) for more information.
1503
#[derive(Debug, Clone)]
1504
#[cfg(feature = "alloc")]
1505
pub struct Wrap {
1506
    /// Wrapping width
1507
    ///
1508
    /// Must be a multiple of:
1509
    ///
1510
    /// - 8 for a bit-width of 1 (binary), 3 (octal), and 5 (base32)
1511
    /// - 4 for a bit-width of 2 (base4) and 6 (base64)
1512
    /// - 2 for a bit-width of 4 (hexadecimal)
1513
    ///
1514
    /// Wrapping is disabled if null.
1515
    pub width: usize,
1516

1517
    /// Wrapping characters
1518
    ///
1519
    /// Wrapping is disabled if empty.
1520
    pub separator: String,
1521
}
1522

1523
/// Base-conversion specification
1524
///
1525
/// It is possible to define custom encodings given a specification. To do so, it is important to
1526
/// understand the theory first.
1527
///
1528
/// # Theory
1529
///
1530
/// Each subsection has an equivalent subsection in the [Practice](#practice) section.
1531
///
1532
/// ## Basics
1533
///
1534
/// The main idea of a [base-conversion] encoding is to see `[u8]` as numbers written in
1535
/// little-endian base256 and convert them in another little-endian base. For performance reasons,
1536
/// this crate restricts this other base to be of size 2 (binary), 4 (base4), 8 (octal), 16
1537
/// (hexadecimal), 32 (base32), or 64 (base64). The converted number is written as `[u8]` although
1538
/// it doesn't use all the 256 possible values of `u8`. This crate encodes to ASCII, so only values
1539
/// smaller than 128 are allowed.
1540
///
1541
/// More precisely, we need the following elements:
1542
///
1543
/// - The bit-width N: 1 for binary, 2 for base4, 3 for octal, 4 for hexadecimal, 5 for base32, and
1544
///   6 for base64
1545
/// - The [bit-order](enum.BitOrder.html): most or least significant bit first
1546
/// - The symbols function S from [0, 2<sup>N</sup>) (called values and written `uN`) to symbols
1547
///   (represented as `u8` although only ASCII symbols are allowed, i.e. smaller than 128)
1548
/// - The values partial function V from ASCII to [0, 2<sup>N</sup>), i.e. from `u8` to `uN`
1549
/// - Whether trailing bits are checked: trailing bits are leading zeros in theory, but since
1550
///   numbers are little-endian they come last
1551
///
1552
/// For the encoding to be correct (i.e. encoding then decoding gives back the initial input),
1553
/// V(S(i)) must be defined and equal to i for all i in [0, 2<sup>N</sup>). For the encoding to be
1554
/// [canonical][canonical] (i.e. different inputs decode to different outputs, or equivalently,
1555
/// decoding then encoding gives back the initial input), trailing bits must be checked and if V(i)
1556
/// is defined then S(V(i)) is equal to i for all i.
1557
///
1558
/// Encoding and decoding are given by the following pipeline:
1559
///
1560
/// ```text
1561
/// [u8] <--1--> [[bit; 8]] <--2--> [[bit; N]] <--3--> [uN] <--4--> [u8]
1562
/// 1: Map bit-order between each u8 and [bit; 8]
1563
/// 2: Base conversion between base 2^8 and base 2^N (check trailing bits)
1564
/// 3: Map bit-order between each [bit; N] and uN
1565
/// 4: Map symbols/values between each uN and u8 (values must be defined)
1566
/// ```
1567
///
1568
/// ## Extensions
1569
///
1570
/// All these extensions make the encoding not canonical.
1571
///
1572
/// ### Padding
1573
///
1574
/// Padding is useful if the following conditions are met:
1575
///
1576
/// - the bit-width is 3 (octal), 5 (base32), or 6 (base64)
1577
/// - the length of the data to encode is not known in advance
1578
/// - the data must be sent without buffering
1579
///
1580
/// Bases for which the bit-width N does not divide 8 may not concatenate encoded data. This comes
1581
/// from the fact that it is not possible to make the difference between trailing bits and encoding
1582
/// bits. Padding solves this issue by adding a new character to discriminate between trailing bits
1583
/// and encoding bits. The idea is to work by blocks of lcm(8, N) bits, where lcm(8, N) is the least
1584
/// common multiple of 8 and N. When such block is not complete, it is padded.
1585
///
1586
/// To preserve correctness, the padding character must not be a symbol.
1587
///
1588
/// ### Ignore characters when decoding
1589
///
1590
/// Ignoring characters when decoding is useful if after encoding some characters are added for
1591
/// convenience or any other reason (like wrapping). In that case we want to first ignore those
1592
/// characters before decoding.
1593
///
1594
/// To preserve correctness, ignored characters must not contain symbols or the padding character.
1595
///
1596
/// ### Wrap output when encoding
1597
///
1598
/// Wrapping output when encoding is useful if the output is meant to be printed in a document where
1599
/// width is limited (typically 80-columns documents). In that case, the wrapping width and the
1600
/// wrapping separator have to be defined.
1601
///
1602
/// To preserve correctness, the wrapping separator characters must be ignored (see previous
1603
/// subsection). As such, wrapping separator characters must also not contain symbols or the padding
1604
/// character.
1605
///
1606
/// ### Translate characters when decoding
1607
///
1608
/// Translating characters when decoding is useful when encoded data may be copied by a humain
1609
/// instead of a machine. Humans tend to confuse some characters for others. In that case we want to
1610
/// translate those characters before decoding.
1611
///
1612
/// To preserve correctness, the characters we translate _from_ must not contain symbols or the
1613
/// padding character, and the characters we translate _to_ must only contain symbols or the padding
1614
/// character.
1615
///
1616
/// # Practice
1617
///
1618
/// ## Basics
1619
///
1620
/// ```rust
1621
/// use data_encoding_v3::{DynEncoding, Specification};
1622
/// fn make_encoding(symbols: &str) -> DynEncoding {
1623
///     let mut spec = Specification::new();
1624
///     spec.symbols.push_str(symbols);
1625
///     spec.encoding().unwrap()
1626
/// }
1627
/// let binary = make_encoding("01");
1628
/// let octal = make_encoding("01234567");
1629
/// let hexadecimal = make_encoding("0123456789abcdef");
1630
/// assert_eq!(binary.encode(b"Bit"), "010000100110100101110100");
1631
/// assert_eq!(octal.encode(b"Bit"), "20464564");
1632
/// assert_eq!(hexadecimal.encode(b"Bit"), "426974");
1633
/// ```
1634
///
1635
/// The `binary` base has 2 symbols `0` and `1` with value 0 and 1 respectively. The `octal` base
1636
/// has 8 symbols `0` to `7` with value 0 to 7. The `hexadecimal` base has 16 symbols `0` to `9` and
1637
/// `a` to `f` with value 0 to 15. The following diagram gives the idea of how encoding works in the
1638
/// previous example (note that we can actually write such diagram only because the bit-order is
1639
/// most significant first):
1640
///
1641
/// ```text
1642
/// [      octal] |  2  :  0  :  4  :  6  :  4  :  5  :  6  :  4  |
1643
/// [     binary] |0 1 0 0 0 0 1 0|0 1 1 0 1 0 0 1|0 1 1 1 0 1 0 0|
1644
/// [hexadecimal] |   4   :   2   |   6   :   9   |   7   :   4   |
1645
///                ^-- LSB                                       ^-- MSB
1646
/// ```
1647
///
1648
/// Note that in theory, these little-endian numbers are read from right to left (the most
1649
/// significant bit is at the right). Since leading zeros are meaningless (in our usual decimal
1650
/// notation 0123 is the same as 123), it explains why trailing bits must be zero. Trailing bits may
1651
/// occur when the bit-width of a base does not divide 8. Only binary, base4, and hexadecimal don't
1652
/// have trailing bits issues. So let's consider octal and base64, which have trailing bits in
1653
/// similar circumstances:
1654
///
1655
/// ```rust
1656
/// use data_encoding_v3::{Specification, BASE64_NOPAD};
1657
/// let octal = {
1658
///     let mut spec = Specification::new();
1659
///     spec.symbols.push_str("01234567");
1660
///     spec.encoding().unwrap()
1661
/// };
1662
/// assert_eq!(BASE64_NOPAD.encode(b"B"), "Qg");
1663
/// assert_eq!(octal.encode(b"B"), "204");
1664
/// ```
1665
///
1666
/// We have the following diagram, where the base64 values are written between parentheses:
1667
///
1668
/// ```text
1669
/// [base64] |   Q(16)   :   g(32)   : [has 4 zero trailing bits]
1670
/// [ octal] |  2  :  0  :  4  :       [has 1 zero trailing bit ]
1671
///          |0 1 0 0 0 0 1 0|0 0 0 0
1672
/// [ ascii] |       B       |
1673
///                           ^-^-^-^-- leading zeros / trailing bits
1674
/// ```
1675
///
1676
/// ## Extensions
1677
///
1678
/// ### Padding
1679
///
1680
/// For octal and base64, lcm(8, 3) == lcm(8, 6) == 24 bits or 3 bytes. For base32, lcm(8, 5) is 40
1681
/// bits or 5 bytes. Let's consider octal and base64:
1682
///
1683
/// ```rust
1684
/// use data_encoding_v3::{Specification, BASE64};
1685
/// let octal = {
1686
///     let mut spec = Specification::new();
1687
///     spec.symbols.push_str("01234567");
1688
///     spec.padding = Some('=');
1689
///     spec.encoding().unwrap()
1690
/// };
1691
/// // We start encoding but we only have "B" for now.
1692
/// assert_eq!(BASE64.encode(b"B"), "Qg==");
1693
/// assert_eq!(octal.encode(b"B"), "204=====");
1694
/// // Now we have "it".
1695
/// assert_eq!(BASE64.encode(b"it"), "aXQ=");
1696
/// assert_eq!(octal.encode(b"it"), "322720==");
1697
/// // By concatenating everything, we may decode the original data.
1698
/// assert_eq!(BASE64.decode(b"Qg==aXQ=").unwrap(), b"Bit");
1699
/// assert_eq!(octal.decode(b"204=====322720==").unwrap(), b"Bit");
1700
/// ```
1701
///
1702
/// We have the following diagrams:
1703
///
1704
/// ```text
1705
/// [base64] |   Q(16)   :   g(32)   :     =     :     =     |
1706
/// [ octal] |  2  :  0  :  4  :  =  :  =  :  =  :  =  :  =  |
1707
///          |0 1 0 0 0 0 1 0|. . . . . . . .|. . . . . . . .|
1708
/// [ ascii] |       B       |        end of block aligned --^
1709
///          ^-- beginning of block aligned
1710
///
1711
/// [base64] |   a(26)   :   X(23)   :   Q(16)   :     =     |
1712
/// [ octal] |  3  :  2  :  2  :  7  :  2  :  0  :  =  :  =  |
1713
///          |0 1 1 0 1 0 0 1|0 1 1 1 0 1 0 0|. . . . . . . .|
1714
/// [ ascii] |       i       |       t       |
1715
/// ```
1716
///
1717
/// ### Ignore characters when decoding
1718
///
1719
/// The typical use-case is to ignore newlines (`\r` and `\n`). But to keep the example small, we
1720
/// will ignore spaces.
1721
///
1722
/// ```rust
1723
/// let mut spec = data_encoding_v3::HEXLOWER.specification();
1724
/// spec.ignore.push_str(" \t");
1725
/// let base = spec.encoding().unwrap();
1726
/// assert_eq!(base.decode(b"42 69 74"), base.decode(b"426974"));
1727
/// ```
1728
///
1729
/// ### Wrap output when encoding
1730
///
1731
/// The typical use-case is to wrap after 64 or 76 characters with a newline (`\r\n` or `\n`). But
1732
/// to keep the example small, we will wrap after 8 characters with a space.
1733
///
1734
/// ```rust
1735
/// let mut spec = data_encoding_v3::BASE64.specification();
1736
/// spec.wrap.width = 8;
1737
/// spec.wrap.separator.push_str(" ");
1738
/// let base64 = spec.encoding().unwrap();
1739
/// assert_eq!(base64.encode(b"Hey you"), "SGV5IHlv dQ== ");
1740
/// ```
1741
///
1742
/// Note that the output always ends with the separator.
1743
///
1744
/// ### Translate characters when decoding
1745
///
1746
/// The typical use-case is to translate lowercase to uppercase or reciprocally, but it is also used
1747
/// for letters that look alike, like `O0` or `Il1`. Let's illustrate both examples.
1748
///
1749
/// ```rust
1750
/// let mut spec = data_encoding_v3::HEXLOWER.specification();
1751
/// spec.translate.from.push_str("ABCDEFOIl");
1752
/// spec.translate.to.push_str("abcdef011");
1753
/// let base = spec.encoding().unwrap();
1754
/// assert_eq!(base.decode(b"BOIl"), base.decode(b"b011"));
1755
/// ```
1756
///
1757
/// [base-conversion]: https://en.wikipedia.org/wiki/Positional_notation#Base_conversion
1758
/// [canonical]: https://tools.ietf.org/html/rfc4648#section-3.5
1759
#[derive(Debug, Clone)]
1760
#[cfg(feature = "alloc")]
1761
pub struct Specification {
1762
    /// Symbols
1763
    ///
1764
    /// The number of symbols must be 2, 4, 8, 16, 32, or 64. Symbols must be ASCII characters
1765
    /// (smaller than 128) and they must be unique.
1766
    pub symbols: String,
1767

1768
    /// Bit-order
1769
    ///
1770
    /// The default is to use most significant bit first since it is the most common.
1771
    pub bit_order: BitOrder,
1772

1773
    /// Check trailing bits
1774
    ///
1775
    /// The default is to check trailing bits. This field is ignored when unnecessary (i.e. for
1776
    /// base2, base4, and base16).
1777
    pub check_trailing_bits: bool,
1778

1779
    /// Padding
1780
    ///
1781
    /// The default is to not use padding. The padding character must be ASCII and must not be a
1782
    /// symbol.
1783
    pub padding: Option<char>,
1784

1785
    /// Characters to ignore when decoding
1786
    ///
1787
    /// The default is to not ignore characters when decoding. The characters to ignore must be
1788
    /// ASCII and must not be symbols or the padding character.
1789
    pub ignore: String,
1790

1791
    /// How to wrap the output when encoding
1792
    ///
1793
    /// The default is to not wrap the output when encoding. The wrapping characters must be ASCII
1794
    /// and must not be symbols or the padding character.
1795
    pub wrap: Wrap,
1796

1797
    /// How to translate characters when decoding
1798
    ///
1799
    /// The default is to not translate characters when decoding. The characters to translate from
1800
    /// must be ASCII and must not have already been assigned a semantics. The characters to
1801
    /// translate to must be ASCII and must have been assigned a semantics (symbol, padding
1802
    /// character, or ignored character).
1803
    pub translate: Translate,
1804
}
1805

1806
#[cfg(feature = "alloc")]
1807
impl Default for Specification {
1808
    fn default() -> Self {
1809
        Self::new()
1810
    }
1811
}
1812

1813
#[derive(Debug, Copy, Clone)]
1814
#[cfg(feature = "alloc")]
1815
enum SpecificationErrorImpl {
1816
    BadSize,
1817
    NotAscii,
1818
    Duplicate(u8),
1819
    ExtraPadding,
1820
    WrapLength,
1821
    WrapWidth(u8),
1822
    FromTo,
1823
    Undefined(u8),
1824
}
1825
#[cfg(feature = "alloc")]
1826
use crate::SpecificationErrorImpl::*;
1827

1828
/// Specification error
1829
#[derive(Debug, Copy, Clone)]
1830
#[cfg(feature = "alloc")]
1831
pub struct SpecificationError(SpecificationErrorImpl);
1832

1833
#[cfg(feature = "alloc")]
1834
impl core::fmt::Display for SpecificationError {
1835
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1836
        match self.0 {
1837
            BadSize => write!(f, "invalid number of symbols"),
1838
            NotAscii => write!(f, "non-ascii character"),
1839
            Duplicate(c) => write!(f, "{:?} has conflicting definitions", c as char),
1840
            ExtraPadding => write!(f, "unnecessary padding"),
1841
            WrapLength => write!(f, "invalid wrap width or separator length"),
1842
            WrapWidth(x) => write!(f, "wrap width not a multiple of {x}"),
1843
            FromTo => write!(f, "translate from/to length mismatch"),
1844
            Undefined(c) => write!(f, "{:?} is undefined", c as char),
1845
        }
1846
    }
1847
}
1848

1849
#[cfg(feature = "std")]
1850
impl std::error::Error for SpecificationError {
1851
    fn description(&self) -> &str {
1852
        match self.0 {
1853
            BadSize => "invalid number of symbols",
1854
            NotAscii => "non-ascii character",
1855
            Duplicate(_) => "conflicting definitions",
1856
            ExtraPadding => "unnecessary padding",
1857
            WrapLength => "invalid wrap width or separator length",
1858
            WrapWidth(_) => "wrap width not a multiple",
1859
            FromTo => "translate from/to length mismatch",
1860
            Undefined(_) => "undefined character",
1861
        }
1862
    }
1863
}
1864

1865
#[cfg(feature = "alloc")]
1866
impl Specification {
1867
    /// Returns a default specification
1868
    #[must_use]
1869
    pub fn new() -> Specification {
1870
        Specification {
1871
            symbols: String::new(),
1872
            bit_order: MostSignificantFirst,
1873
            check_trailing_bits: true,
1874
            padding: None,
1875
            ignore: String::new(),
1876
            wrap: Wrap { width: 0, separator: String::new() },
1877
            translate: Translate { from: String::new(), to: String::new() },
1878
        }
1879
    }
1880

1881
    /// Returns the specified encoding
1882
    ///
1883
    /// # Errors
1884
    ///
1885
    /// Returns an error if the specification is invalid.
1886
    pub fn encoding(&self) -> Result<DynEncoding, SpecificationError> {
1887
        let symbols = self.symbols.as_bytes();
1888
        let bit: u8 = match symbols.len() {
1889
            2 => 1,
1890
            4 => 2,
1891
            8 => 3,
1892
            16 => 4,
1893
            32 => 5,
1894
            64 => 6,
1895
            _ => return Err(SpecificationError(BadSize)),
1896
        };
1897
        let mut values = [INVALID; 128];
1898
        let set = |v: &mut [u8; 128], i: u8, x: u8| {
1899
            check!(SpecificationError(NotAscii), i < 128);
1900
            if v[i as usize] == x {
1901
                return Ok(());
1902
            }
1903
            check!(SpecificationError(Duplicate(i)), v[i as usize] == INVALID);
1904
            v[i as usize] = x;
1905
            Ok(())
1906
        };
1907
        for (v, symbols) in symbols.iter().enumerate() {
1908
            #[allow(clippy::cast_possible_truncation)] // no truncation
1909
            set(&mut values, *symbols, v as u8)?;
1910
        }
1911
        let msb = self.bit_order == MostSignificantFirst;
1912
        let ctb = self.check_trailing_bits || 8 % bit == 0;
1913
        let pad = match self.padding {
1914
            None => None,
1915
            Some(pad) => {
1916
                check!(SpecificationError(ExtraPadding), 8 % bit != 0);
1917
                check!(SpecificationError(NotAscii), pad.len_utf8() == 1);
1918
                set(&mut values, pad as u8, PADDING)?;
1919
                Some(pad as u8)
1920
            }
1921
        };
1922
        for i in self.ignore.bytes() {
1923
            set(&mut values, i, IGNORE)?;
1924
        }
1925
        let wrap = if self.wrap.separator.is_empty() || self.wrap.width == 0 {
1926
            None
1927
        } else {
1928
            let col = self.wrap.width;
1929
            let end = self.wrap.separator.as_bytes();
1930
            check!(SpecificationError(WrapLength), col < 256 && end.len() < 256);
1931
            #[allow(clippy::cast_possible_truncation)] // no truncation
1932
            let col = col as u8;
1933
            #[allow(clippy::cast_possible_truncation)] // no truncation
1934
            let dec = dec(bit as usize) as u8;
1935
            check!(SpecificationError(WrapWidth(dec)), col % dec == 0);
1936
            for &i in end {
1937
                set(&mut values, i, IGNORE)?;
1938
            }
1939
            Some((col, end))
1940
        };
1941
        let from = self.translate.from.as_bytes();
1942
        let to = self.translate.to.as_bytes();
1943
        check!(SpecificationError(FromTo), from.len() == to.len());
1944
        for i in 0 .. from.len() {
1945
            check!(SpecificationError(NotAscii), to[i] < 128);
1946
            let v = values[to[i] as usize];
1947
            check!(SpecificationError(Undefined(to[i])), v != INVALID);
1948
            set(&mut values, from[i], v)?;
1949
        }
1950
        let mut encoding = Vec::new();
1951
        for _ in 0 .. 256 / symbols.len() {
1952
            encoding.extend_from_slice(symbols);
1953
        }
1954
        encoding.extend_from_slice(&values);
1955
        encoding.extend_from_slice(&[INVALID; 128]);
1956
        match pad {
1957
            None => encoding.push(INVALID),
1958
            Some(pad) => encoding.push(pad),
1959
        }
1960
        encoding.push(bit);
1961
        if msb {
1962
            encoding[513] |= 0x08;
1963
        }
1964
        if ctb {
1965
            encoding[513] |= 0x10;
1966
        }
1967
        if let Some((col, end)) = wrap {
1968
            encoding.push(col);
1969
            encoding.extend_from_slice(end);
1970
        } else if values.contains(&IGNORE) {
1971
            encoding.push(0);
1972
        }
1973
        Ok(DynEncoding(Cow::Owned(encoding)))
1974
    }
1975
}
1976

1977
/// Hexadecimal encoding.
1978
pub type Hex = Encoding<Bit4, True, False, False, False>;
1979

1980
/// Base32 encoding.
1981
pub type Base32 = Encoding<Bit5, True, True, False, False>;
1982

1983
/// Base32 encoding (no padding).
1984
pub type Base32NoPad = Encoding<Bit5, True, False, False, False>;
1985

1986
/// Base32 encoding (LSB first, no padding).
1987
pub type Base32LsbNoPad = Encoding<Bit5, False, False, False, False>;
1988

1989
/// Base64 encoding.
1990
pub type Base64 = Encoding<Bit6, True, True, False, False>;
1991

1992
/// Base64 encoding (no padding).
1993
pub type Base64NoPad = Encoding<Bit6, True, False, False, False>;
1994

1995
/// Base64 encoding (wrap).
1996
pub type Base64Wrap = Encoding<Bit6, True, True, True, True>;
1997

1998
/// Lowercase hexadecimal encoding
1999
///
2000
/// This encoding is a static version of:
2001
///
2002
/// ```rust
2003
/// # use data_encoding_v3::{Specification, HEXLOWER};
2004
/// let mut spec = Specification::new();
2005
/// spec.symbols.push_str("0123456789abcdef");
2006
/// assert_eq!(HEXLOWER.as_dyn(), &spec.encoding().unwrap());
2007
/// ```
2008
///
2009
/// # Examples
2010
///
2011
/// ```rust
2012
/// use data_encoding_v3::HEXLOWER;
2013
/// let deadbeef = vec![0xde, 0xad, 0xbe, 0xef];
2014
/// assert_eq!(HEXLOWER.decode(b"deadbeef").unwrap(), deadbeef);
2015
/// assert_eq!(HEXLOWER.encode(&deadbeef), "deadbeef");
2016
/// ```
2017
pub static HEXLOWER: Hex = unsafe { Hex::new_unchecked(HEXLOWER_IMPL) };
2018
const HEXLOWER_IMPL: &[u8] = &[
2019
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54,
2020
    55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100,
2021
    101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51,
2022
    52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
2023
    98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48,
2024
    49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55,
2025
    56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100,
2026
    101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51,
2027
    52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
2028
    98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48,
2029
    49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55,
2030
    56, 57, 97, 98, 99, 100, 101, 102, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2031
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2032
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 1, 2,
2033
    3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2034
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2035
    128, 128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2036
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2037
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2038
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2039
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2040
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2041
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2042
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2043
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 28,
2044
];
2045

2046
/// Lowercase hexadecimal encoding with case-insensitive decoding
2047
///
2048
/// This encoding is a static version of:
2049
///
2050
/// ```rust
2051
/// # use data_encoding_v3::{Specification, HEXLOWER_PERMISSIVE};
2052
/// let mut spec = Specification::new();
2053
/// spec.symbols.push_str("0123456789abcdef");
2054
/// spec.translate.from.push_str("ABCDEF");
2055
/// spec.translate.to.push_str("abcdef");
2056
/// assert_eq!(HEXLOWER_PERMISSIVE.as_dyn(), &spec.encoding().unwrap());
2057
/// ```
2058
///
2059
/// # Examples
2060
///
2061
/// ```rust
2062
/// use data_encoding_v3::HEXLOWER_PERMISSIVE;
2063
/// let deadbeef = vec![0xde, 0xad, 0xbe, 0xef];
2064
/// assert_eq!(HEXLOWER_PERMISSIVE.decode(b"DeadBeef").unwrap(), deadbeef);
2065
/// assert_eq!(HEXLOWER_PERMISSIVE.encode(&deadbeef), "deadbeef");
2066
/// ```
2067
///
2068
/// You can also define a shorter name:
2069
///
2070
/// ```rust
2071
/// pub use data_encoding_v3::HEXLOWER_PERMISSIVE as HEX;
2072
/// ```
2073
pub static HEXLOWER_PERMISSIVE: Hex = unsafe { Hex::new_unchecked(HEXLOWER_PERMISSIVE_IMPL) };
2074
const HEXLOWER_PERMISSIVE_IMPL: &[u8] = &[
2075
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54,
2076
    55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100,
2077
    101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51,
2078
    52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
2079
    98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48,
2080
    49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55,
2081
    56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100,
2082
    101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51,
2083
    52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
2084
    98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48,
2085
    49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55,
2086
    56, 57, 97, 98, 99, 100, 101, 102, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2087
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2088
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 1, 2,
2089
    3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 128, 128, 128,
2090
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2091
    128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2092
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2093
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2094
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2095
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2096
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2097
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2098
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2099
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 28,
2100
];
2101

2102
/// Uppercase hexadecimal encoding
2103
///
2104
/// This encoding is a static version of:
2105
///
2106
/// ```rust
2107
/// # use data_encoding_v3::{Specification, HEXUPPER};
2108
/// let mut spec = Specification::new();
2109
/// spec.symbols.push_str("0123456789ABCDEF");
2110
/// assert_eq!(HEXUPPER.as_dyn(), &spec.encoding().unwrap());
2111
/// ```
2112
///
2113
/// It is compliant with [RFC4648] and known as "base16" or "hex".
2114
///
2115
/// # Examples
2116
///
2117
/// ```rust
2118
/// use data_encoding_v3::HEXUPPER;
2119
/// let deadbeef = vec![0xde, 0xad, 0xbe, 0xef];
2120
/// assert_eq!(HEXUPPER.decode(b"DEADBEEF").unwrap(), deadbeef);
2121
/// assert_eq!(HEXUPPER.encode(&deadbeef), "DEADBEEF");
2122
/// ```
2123
///
2124
/// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-8
2125
pub static HEXUPPER: Hex = unsafe { Hex::new_unchecked(HEXUPPER_IMPL) };
2126
const HEXUPPER_IMPL: &[u8] = &[
2127
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2128
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2129
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2130
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2131
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2132
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2133
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2134
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2135
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2136
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2137
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 128, 128, 128, 128, 128, 128,
2138
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2139
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2140
    128, 128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11,
2141
    12, 13, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2142
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2143
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2144
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2145
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2146
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2147
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2148
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2149
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2150
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 28,
2151
];
2152

2153
/// Uppercase hexadecimal encoding with case-insensitive decoding
2154
///
2155
/// This encoding is a static version of:
2156
///
2157
/// ```rust
2158
/// # use data_encoding_v3::{Specification, HEXUPPER_PERMISSIVE};
2159
/// let mut spec = Specification::new();
2160
/// spec.symbols.push_str("0123456789ABCDEF");
2161
/// spec.translate.from.push_str("abcdef");
2162
/// spec.translate.to.push_str("ABCDEF");
2163
/// assert_eq!(HEXUPPER_PERMISSIVE.as_dyn(), &spec.encoding().unwrap());
2164
/// ```
2165
///
2166
/// # Examples
2167
///
2168
/// ```rust
2169
/// use data_encoding_v3::HEXUPPER_PERMISSIVE;
2170
/// let deadbeef = vec![0xde, 0xad, 0xbe, 0xef];
2171
/// assert_eq!(HEXUPPER_PERMISSIVE.decode(b"DeadBeef").unwrap(), deadbeef);
2172
/// assert_eq!(HEXUPPER_PERMISSIVE.encode(&deadbeef), "DEADBEEF");
2173
/// ```
2174
pub static HEXUPPER_PERMISSIVE: Hex = unsafe { Hex::new_unchecked(HEXUPPER_PERMISSIVE_IMPL) };
2175
const HEXUPPER_PERMISSIVE_IMPL: &[u8] = &[
2176
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2177
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2178
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2179
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2180
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2181
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2182
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2183
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2184
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
2185
    56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2186
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 128, 128, 128, 128, 128, 128,
2187
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2188
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2189
    128, 128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11,
2190
    12, 13, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2191
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 128, 128, 128, 128,
2192
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2193
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2194
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2195
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2196
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2197
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2198
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2199
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 28,
2200
];
2201

2202
/// Padded base32 encoding
2203
///
2204
/// This encoding is a static version of:
2205
///
2206
/// ```rust
2207
/// # use data_encoding_v3::{Specification, BASE32};
2208
/// let mut spec = Specification::new();
2209
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567");
2210
/// spec.padding = Some('=');
2211
/// assert_eq!(BASE32.as_dyn(), &spec.encoding().unwrap());
2212
/// ```
2213
///
2214
/// It conforms to [RFC4648].
2215
///
2216
/// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-6
2217
pub static BASE32: Base32 = unsafe { Base32::new_unchecked(BASE32_IMPL) };
2218
const BASE32_IMPL: &[u8] = &[
2219
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2220
    89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
2221
    81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72,
2222
    73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55,
2223
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2224
    89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
2225
    81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72,
2226
    73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55,
2227
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2228
    89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
2229
    81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 128, 128, 128, 128, 128, 128,
2230
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2231
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2232
    128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 128, 128, 128, 128, 128, 130, 128, 128,
2233
    128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
2234
    25, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2235
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2236
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2237
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2238
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2239
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2240
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2241
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2242
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 29,
2243
];
2244

2245
/// Unpadded base32 encoding
2246
///
2247
/// This encoding is a static version of:
2248
///
2249
/// ```rust
2250
/// # use data_encoding_v3::{Specification, BASE32_NOPAD};
2251
/// let mut spec = Specification::new();
2252
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567");
2253
/// assert_eq!(BASE32_NOPAD.as_dyn(), &spec.encoding().unwrap());
2254
/// ```
2255
pub static BASE32_NOPAD: Base32NoPad = unsafe { Base32NoPad::new_unchecked(BASE32_NOPAD_IMPL) };
2256
const BASE32_NOPAD_IMPL: &[u8] = &[
2257
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2258
    89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
2259
    81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72,
2260
    73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55,
2261
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2262
    89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
2263
    81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72,
2264
    73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55,
2265
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2266
    89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
2267
    81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 128, 128, 128, 128, 128, 128,
2268
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2269
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2270
    128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 128, 128, 128, 128, 128, 128, 128, 128,
2271
    128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
2272
    25, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2273
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2274
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2275
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2276
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2277
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2278
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2279
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2280
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 29,
2281
];
2282

2283
/// Padded base32hex encoding
2284
///
2285
/// This encoding is a static version of:
2286
///
2287
/// ```rust
2288
/// # use data_encoding_v3::{Specification, BASE32HEX};
2289
/// let mut spec = Specification::new();
2290
/// spec.symbols.push_str("0123456789ABCDEFGHIJKLMNOPQRSTUV");
2291
/// spec.padding = Some('=');
2292
/// assert_eq!(BASE32HEX.as_dyn(), &spec.encoding().unwrap());
2293
/// ```
2294
///
2295
/// It conforms to [RFC4648].
2296
///
2297
/// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-7
2298
pub static BASE32HEX: Base32 = unsafe { Base32::new_unchecked(BASE32HEX_IMPL) };
2299
const BASE32HEX_IMPL: &[u8] = &[
2300
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
2301
    79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2302
    71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55,
2303
    56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
2304
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
2305
    79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2306
    71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55,
2307
    56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
2308
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
2309
    79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2310
    71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 128, 128, 128, 128, 128, 128,
2311
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2312
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2313
    128, 128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 130, 128, 128, 128, 10, 11,
2314
    12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 128, 128, 128,
2315
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2316
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2317
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2318
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2319
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2320
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2321
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2322
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2323
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 29,
2324
];
2325

2326
/// Unpadded base32hex encoding
2327
///
2328
/// This encoding is a static version of:
2329
///
2330
/// ```rust
2331
/// # use data_encoding_v3::{Specification, BASE32HEX_NOPAD};
2332
/// let mut spec = Specification::new();
2333
/// spec.symbols.push_str("0123456789ABCDEFGHIJKLMNOPQRSTUV");
2334
/// assert_eq!(BASE32HEX_NOPAD.as_dyn(), &spec.encoding().unwrap());
2335
/// ```
2336
pub static BASE32HEX_NOPAD: Base32NoPad =
2337
    unsafe { Base32NoPad::new_unchecked(BASE32HEX_NOPAD_IMPL) };
2338
const BASE32HEX_NOPAD_IMPL: &[u8] = &[
2339
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
2340
    79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2341
    71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55,
2342
    56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
2343
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
2344
    79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2345
    71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55,
2346
    56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
2347
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
2348
    79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
2349
    71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 128, 128, 128, 128, 128, 128,
2350
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2351
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2352
    128, 128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11,
2353
    12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 128, 128, 128,
2354
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2355
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2356
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2357
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2358
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2359
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2360
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2361
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2362
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 29,
2363
];
2364

2365
/// DNSSEC base32 encoding
2366
///
2367
/// This encoding is a static version of:
2368
///
2369
/// ```rust
2370
/// # use data_encoding_v3::{Specification, BASE32_DNSSEC};
2371
/// let mut spec = Specification::new();
2372
/// spec.symbols.push_str("0123456789abcdefghijklmnopqrstuv");
2373
/// spec.translate.from.push_str("ABCDEFGHIJKLMNOPQRSTUV");
2374
/// spec.translate.to.push_str("abcdefghijklmnopqrstuv");
2375
/// assert_eq!(BASE32_DNSSEC.as_dyn(), &spec.encoding().unwrap());
2376
/// ```
2377
///
2378
/// It conforms to [RFC5155]:
2379
///
2380
/// - It uses a base32 extended hex alphabet.
2381
/// - It is case-insensitive when decoding and uses lowercase when encoding.
2382
/// - It does not use padding.
2383
///
2384
/// [RFC5155]: https://tools.ietf.org/html/rfc5155
2385
pub static BASE32_DNSSEC: Base32NoPad = unsafe { Base32NoPad::new_unchecked(BASE32_DNSSEC_IMPL) };
2386
const BASE32_DNSSEC_IMPL: &[u8] = &[
2387
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
2388
    108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
2389
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
2390
    116, 117, 118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104,
2391
    105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 48, 49, 50, 51, 52, 53,
2392
    54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
2393
    113, 114, 115, 116, 117, 118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101,
2394
    102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 48, 49,
2395
    50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
2396
    110, 111, 112, 113, 114, 115, 116, 117, 118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98,
2397
    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
2398
    118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
2399
    107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 128, 128, 128, 128, 128, 128, 128,
2400
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2401
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2402
    128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11, 12, 13,
2403
    14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 128, 128, 128, 128,
2404
    128, 128, 128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
2405
    26, 27, 28, 29, 30, 31, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2406
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2407
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2408
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2409
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2410
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2411
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2412
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 29,
2413
];
2414

2415
#[allow(clippy::doc_markdown)]
2416
/// DNSCurve base32 encoding
2417
///
2418
/// This encoding is a static version of:
2419
///
2420
/// ```rust
2421
/// # use data_encoding_v3::{BitOrder, Specification, BASE32_DNSCURVE};
2422
/// let mut spec = Specification::new();
2423
/// spec.symbols.push_str("0123456789bcdfghjklmnpqrstuvwxyz");
2424
/// spec.bit_order = BitOrder::LeastSignificantFirst;
2425
/// spec.translate.from.push_str("BCDFGHJKLMNPQRSTUVWXYZ");
2426
/// spec.translate.to.push_str("bcdfghjklmnpqrstuvwxyz");
2427
/// assert_eq!(BASE32_DNSCURVE.as_dyn(), &spec.encoding().unwrap());
2428
/// ```
2429
///
2430
/// It conforms to [DNSCurve].
2431
///
2432
/// [DNSCurve]: https://dnscurve.org/in-implement.html
2433
pub static BASE32_DNSCURVE: Base32LsbNoPad =
2434
    unsafe { Base32LsbNoPad::new_unchecked(BASE32_DNSCURVE_IMPL) };
2435
const BASE32_DNSCURVE_IMPL: &[u8] = &[
2436
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110,
2437
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
2438
    98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119,
2439
    120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107,
2440
    108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53,
2441
    54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116,
2442
    117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103,
2443
    104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49,
2444
    50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113,
2445
    114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99,
2446
    100, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
2447
    122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109,
2448
    110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 128, 128, 128, 128, 128, 128, 128,
2449
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2450
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2451
    128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 128, 10, 11,
2452
    12, 128, 13, 14, 15, 128, 16, 17, 18, 19, 20, 128, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
2453
    128, 128, 128, 128, 128, 128, 128, 10, 11, 12, 128, 13, 14, 15, 128, 16, 17, 18, 19, 20, 128,
2454
    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2455
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2456
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2457
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2458
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2459
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2460
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2461
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 21,
2462
];
2463

2464
/// Padded base64 encoding
2465
///
2466
/// This encoding is a static version of:
2467
///
2468
/// ```rust
2469
/// # use data_encoding_v3::{Specification, BASE64};
2470
/// let mut spec = Specification::new();
2471
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
2472
/// spec.padding = Some('=');
2473
/// assert_eq!(BASE64.as_dyn(), &spec.encoding().unwrap());
2474
/// ```
2475
///
2476
/// It conforms to [RFC4648].
2477
///
2478
/// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-4
2479
pub static BASE64: Base64 = unsafe { Base64::new_unchecked(BASE64_IMPL) };
2480
const BASE64_IMPL: &[u8] = &[
2481
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2482
    89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
2483
    115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66,
2484
    67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
2485
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
2486
    116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67,
2487
    68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
2488
    98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
2489
    117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67, 68,
2490
    69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
2491
    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
2492
    118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 128, 128, 128, 128,
2493
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2494
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2495
    128, 62, 128, 128, 128, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 130, 128,
2496
    128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
2497
    24, 25, 128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
2498
    40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2499
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2500
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2501
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2502
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2503
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2504
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2505
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 30,
2506
];
2507

2508
/// Unpadded base64 encoding
2509
///
2510
/// This encoding is a static version of:
2511
///
2512
/// ```rust
2513
/// # use data_encoding_v3::{Specification, BASE64_NOPAD};
2514
/// let mut spec = Specification::new();
2515
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
2516
/// assert_eq!(BASE64_NOPAD.as_dyn(), &spec.encoding().unwrap());
2517
/// ```
2518
pub static BASE64_NOPAD: Base64NoPad = unsafe { Base64NoPad::new_unchecked(BASE64_NOPAD_IMPL) };
2519
const BASE64_NOPAD_IMPL: &[u8] = &[
2520
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2521
    89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
2522
    115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66,
2523
    67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
2524
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
2525
    116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67,
2526
    68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
2527
    98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
2528
    117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67, 68,
2529
    69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
2530
    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
2531
    118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 128, 128, 128, 128,
2532
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2533
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2534
    128, 62, 128, 128, 128, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 128, 128,
2535
    128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
2536
    24, 25, 128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
2537
    40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2538
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2539
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2540
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2541
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2542
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2543
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2544
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 30,
2545
];
2546

2547
/// MIME base64 encoding
2548
///
2549
/// This encoding is a static version of:
2550
///
2551
/// ```rust
2552
/// # use data_encoding_v3::{Specification, BASE64_MIME};
2553
/// let mut spec = Specification::new();
2554
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
2555
/// spec.padding = Some('=');
2556
/// spec.wrap.width = 76;
2557
/// spec.wrap.separator.push_str("\r\n");
2558
/// assert_eq!(BASE64_MIME.as_dyn(), &spec.encoding().unwrap());
2559
/// ```
2560
///
2561
/// It does not exactly conform to [RFC2045] because it does not print the header
2562
/// and does not ignore all characters.
2563
///
2564
/// [RFC2045]: https://tools.ietf.org/html/rfc2045
2565
pub static BASE64_MIME: Base64Wrap = unsafe { Base64Wrap::new_unchecked(BASE64_MIME_IMPL) };
2566
const BASE64_MIME_IMPL: &[u8] = &[
2567
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2568
    89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
2569
    115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66,
2570
    67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
2571
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
2572
    116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67,
2573
    68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
2574
    98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
2575
    117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67, 68,
2576
    69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
2577
    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
2578
    118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 128, 128, 128, 128,
2579
    128, 128, 128, 128, 128, 128, 129, 128, 128, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2580
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2581
    128, 62, 128, 128, 128, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 130, 128,
2582
    128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
2583
    24, 25, 128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
2584
    40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2585
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2586
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2587
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2588
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2589
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2590
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2591
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 30, 76, 13, 10,
2592
];
2593

2594
/// MIME base64 encoding without trailing bits check
2595
///
2596
/// This encoding is a static version of:
2597
///
2598
/// ```rust
2599
/// # use data_encoding_v3::{Specification, BASE64_MIME_PERMISSIVE};
2600
/// let mut spec = Specification::new();
2601
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
2602
/// spec.padding = Some('=');
2603
/// spec.wrap.width = 76;
2604
/// spec.wrap.separator.push_str("\r\n");
2605
/// spec.check_trailing_bits = false;
2606
/// assert_eq!(BASE64_MIME_PERMISSIVE.as_dyn(), &spec.encoding().unwrap());
2607
/// ```
2608
///
2609
/// It does not exactly conform to [RFC2045] because it does not print the header
2610
/// and does not ignore all characters.
2611
///
2612
/// [RFC2045]: https://tools.ietf.org/html/rfc2045
2613
pub static BASE64_MIME_PERMISSIVE: Base64Wrap =
2614
    unsafe { Base64Wrap::new_unchecked(BASE64_MIME_PERMISSIVE_IMPL) };
2615
const BASE64_MIME_PERMISSIVE_IMPL: &[u8] = &[
2616
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2617
    89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
2618
    115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66,
2619
    67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
2620
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
2621
    116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67,
2622
    68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
2623
    98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
2624
    117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67, 68,
2625
    69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
2626
    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
2627
    118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 128, 128, 128, 128,
2628
    128, 128, 128, 128, 128, 128, 129, 128, 128, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2629
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2630
    128, 62, 128, 128, 128, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 130, 128,
2631
    128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
2632
    24, 25, 128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
2633
    40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2634
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2635
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2636
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2637
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2638
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2639
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2640
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 14, 76, 13, 10,
2641
];
2642

2643
/// Padded base64url encoding
2644
///
2645
/// This encoding is a static version of:
2646
///
2647
/// ```rust
2648
/// # use data_encoding_v3::{Specification, BASE64URL};
2649
/// let mut spec = Specification::new();
2650
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
2651
/// spec.padding = Some('=');
2652
/// assert_eq!(BASE64URL.as_dyn(), &spec.encoding().unwrap());
2653
/// ```
2654
///
2655
/// It conforms to [RFC4648].
2656
///
2657
/// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-5
2658
pub static BASE64URL: Base64 = unsafe { Base64::new_unchecked(BASE64URL_IMPL) };
2659
const BASE64URL_IMPL: &[u8] = &[
2660
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2661
    89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
2662
    115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66,
2663
    67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
2664
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
2665
    116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66, 67,
2666
    68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
2667
    98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
2668
    117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66, 67, 68,
2669
    69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
2670
    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
2671
    118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 128, 128, 128, 128,
2672
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2673
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2674
    128, 128, 128, 62, 128, 128, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 130, 128,
2675
    128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
2676
    24, 25, 128, 128, 128, 128, 63, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
2677
    40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2678
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2679
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2680
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2681
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2682
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2683
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2684
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 30,
2685
];
2686

2687
/// Unpadded base64url encoding
2688
///
2689
/// This encoding is a static version of:
2690
///
2691
/// ```rust
2692
/// # use data_encoding_v3::{Specification, BASE64URL_NOPAD};
2693
/// let mut spec = Specification::new();
2694
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
2695
/// assert_eq!(BASE64URL_NOPAD.as_dyn(), &spec.encoding().unwrap());
2696
/// ```
2697
pub static BASE64URL_NOPAD: Base64NoPad =
2698
    unsafe { Base64NoPad::new_unchecked(BASE64URL_NOPAD_IMPL) };
2699
const BASE64URL_NOPAD_IMPL: &[u8] = &[
2700
    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
2701
    89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
2702
    115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66,
2703
    67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
2704
    97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
2705
    116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66, 67,
2706
    68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
2707
    98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
2708
    117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66, 67, 68,
2709
    69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
2710
    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
2711
    118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 128, 128, 128, 128,
2712
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2713
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2714
    128, 128, 128, 62, 128, 128, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 128, 128,
2715
    128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
2716
    24, 25, 128, 128, 128, 128, 63, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
2717
    40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2718
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2719
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2720
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2721
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2722
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2723
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
2724
    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 30,
2725
];
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc