Source code

Revision control

Copy as Markdown

Other Tools

//! Efficient and customizable data-encoding functions like base64, base32, and hex
//!
//! This [crate] provides little-endian ASCII base-conversion encodings for
//! bases of size 2, 4, 8, 16, 32, and 64. It supports:
//!
//! - [padding] for streaming
//! - canonical encodings (e.g. [trailing bits] are checked)
//! - in-place [encoding] and [decoding] functions
//! - partial [decoding] functions (e.g. for error recovery)
//! - character [translation] (e.g. for case-insensitivity)
//! - most and least significant [bit-order]
//! - [ignoring] characters when decoding (e.g. for skipping newlines)
//! - [wrapping] the output when encoding
//! - no-std environments with `default-features = false, features = ["alloc"]`
//! - no-alloc environments with `default-features = false`
//!
//! You may use the [binary] or the [website] to play around.
//!
//! # Examples
//!
//! This crate provides predefined encodings as [constants]. These constants are of type
//! [`Encoding`]. This type provides encoding and decoding functions with in-place or allocating
//! variants. Here is an example using the allocating encoding function of [`BASE64`]:
//!
//! ```rust
//! use data_encoding::BASE64;
//! assert_eq!(BASE64.encode(b"Hello world"), "SGVsbG8gd29ybGQ=");
//! ```
//!
//! Here is an example using the in-place decoding function of [`BASE32`]:
//!
//! ```rust
//! use data_encoding::BASE32;
//! let input = b"JBSWY3DPEB3W64TMMQ======";
//! let mut output = vec![0; BASE32.decode_len(input.len()).unwrap()];
//! let len = BASE32.decode_mut(input, &mut output).unwrap();
//! assert_eq!(&output[0 .. len], b"Hello world");
//! ```
//!
//! You are not limited to the predefined encodings. You may define your own encodings (with the
//! same correctness and performance properties as the predefined ones) using the [`Specification`]
//! type:
//!
//! ```rust
//! use data_encoding::Specification;
//! let hex = {
//! let mut spec = Specification::new();
//! spec.symbols.push_str("0123456789abcdef");
//! spec.encoding().unwrap()
//! };
//! assert_eq!(hex.encode(b"hello"), "68656c6c6f");
//! ```
//!
//! You may use the [macro] library to define a compile-time custom encoding:
//!
//! ```rust,ignore
//! use data_encoding::Encoding;
//! use data_encoding_macro::new_encoding;
//! const HEX: Encoding = new_encoding!{
//! symbols: "0123456789abcdef",
//! translate_from: "ABCDEF",
//! translate_to: "abcdef",
//! };
//! const BASE64: Encoding = new_encoding!{
//! symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
//! padding: '=',
//! };
//! ```
//!
//! # Properties
//!
//! The [`HEXUPPER`], [`BASE32`], [`BASE32HEX`], [`BASE64`], and [`BASE64URL`] predefined encodings
//! are conform to [RFC4648].
//!
//! In general, the encoding and decoding functions satisfy the following properties:
//!
//! - They are deterministic: their output only depends on their input
//! - They have no side-effects: they do not modify a hidden mutable state
//! - They are correct: encoding then decoding gives the initial data
//! - They are canonical (unless [`is_canonical`] returns false): decoding then encoding gives the
//! initial data
//!
//! This last property is usually not satisfied by base64 implementations. This is a matter of
//! choice and this crate has made the choice to let the user choose. Support for canonical encoding
//! as described by the [RFC][canonical] is provided. But it is also possible to disable checking
//! trailing bits, to add characters translation, to decode concatenated padded inputs, and to
//! ignore some characters.
//!
//! Since the RFC specifies the encoding function on all inputs and the decoding function on all
//! possible encoded outputs, the differences between implementations come from the decoding
//! function which may be more or less permissive. In this crate, the decoding function of canonical
//! encodings rejects all inputs that are not a possible output of the encoding function. Here are
//! some concrete examples of decoding differences between this crate, the `base64` crate, and the
//! `base64` GNU program:
//!
//! | Input | `data-encoding` | `base64` | GNU `base64` |
//! | ---------- | --------------- | --------- | ------------- |
//! | `AAB=` | `Trailing(2)` | `Last(2)` | `\x00\x00` |
//! | `AA\nB=` | `Length(4)` | `Length` | `\x00\x00` |
//! | `AAB` | `Length(0)` | `Last(2)` | Invalid input |
//! | `AAA` | `Length(0)` | `[0, 0]` | Invalid input |
//! | `A\rA\nB=` | `Length(4)` | `Byte(1)` | Invalid input |
//! | `-_\r\n` | `Symbol(0)` | `Byte(0)` | Invalid input |
//! | `AA==AA==` | `[0, 0]` | `Byte(2)` | `\x00\x00` |
//!
//! We can summarize these discrepancies as follows:
//!
//! | Discrepancy | `data-encoding` | `base64` | GNU `base64` |
//! | -------------------------- | --------------- | -------- | ------------ |
//! | Check trailing bits | Yes | Yes | No |
//! | Ignored characters | None | None | `\n` |
//! | Translated characters | None | None | None |
//! | Check padding | Yes | No | Yes |
//! | Support concatenated input | Yes | No | Yes |
//!
//! This crate permits to disable checking trailing bits. It permits to ignore some characters. It
//! permits to translate characters. It permits to use unpadded encodings. However, for padded
//! encodings, support for concatenated inputs cannot be disabled. This is simply because it doesn't
//! make sense to use padding if it is not to support concatenated inputs.
//!
//! [`BASE32HEX`]: constant.BASE32HEX.html
//! [`BASE32`]: constant.BASE32.html
//! [`BASE64URL`]: constant.BASE64URL.html
//! [`BASE64`]: constant.BASE64.html
//! [`Encoding`]: struct.Encoding.html
//! [`HEXUPPER`]: constant.HEXUPPER.html
//! [`Specification`]: struct.Specification.html
//! [`is_canonical`]: struct.Encoding.html#method.is_canonical
//! [bit-order]: struct.Specification.html#structfield.bit_order
//! [constants]: index.html#constants
//! [decoding]: struct.Encoding.html#method.decode_mut
//! [encoding]: struct.Encoding.html#method.encode_mut
//! [ignoring]: struct.Specification.html#structfield.ignore
//! [padding]: struct.Specification.html#structfield.padding
//! [trailing bits]: struct.Specification.html#structfield.check_trailing_bits
//! [translation]: struct.Specification.html#structfield.translate
//! [website]: https://data-encoding.rs
//! [wrapping]: struct.Specification.html#structfield.wrap
#![no_std]
#![warn(unused_results, missing_docs)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "alloc")]
use alloc::borrow::{Cow, ToOwned};
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::vec;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
macro_rules! check {
($e: expr, $c: expr) => {
if !$c {
return Err($e);
}
};
}
trait Static<T: Copy>: Copy {
fn val(self) -> T;
}
macro_rules! define {
($name: ident: $type: ty = $val: expr) => {
#[derive(Copy, Clone)]
struct $name;
impl Static<$type> for $name {
fn val(self) -> $type {
$val
}
}
};
}
define!(Bf: bool = false);
define!(Bt: bool = true);
define!(N1: usize = 1);
define!(N2: usize = 2);
define!(N3: usize = 3);
define!(N4: usize = 4);
define!(N5: usize = 5);
define!(N6: usize = 6);
#[derive(Copy, Clone)]
struct On;
impl<T: Copy> Static<Option<T>> for On {
fn val(self) -> Option<T> {
None
}
}
#[derive(Copy, Clone)]
struct Os<T>(T);
impl<T: Copy> Static<Option<T>> for Os<T> {
fn val(self) -> Option<T> {
Some(self.0)
}
}
macro_rules! dispatch {
(let $var: ident: bool = $val: expr; $($body: tt)*) => {
if $val {
let $var = Bt; dispatch!($($body)*)
} else {
let $var = Bf; dispatch!($($body)*)
}
};
(let $var: ident: usize = $val: expr; $($body: tt)*) => {
match $val {
1 => { let $var = N1; dispatch!($($body)*) },
2 => { let $var = N2; dispatch!($($body)*) },
3 => { let $var = N3; dispatch!($($body)*) },
4 => { let $var = N4; dispatch!($($body)*) },
5 => { let $var = N5; dispatch!($($body)*) },
6 => { let $var = N6; dispatch!($($body)*) },
_ => panic!(),
}
};
(let $var: ident: Option<$type: ty> = $val: expr; $($body: tt)*) => {
match $val {
None => { let $var = On; dispatch!($($body)*) },
Some(x) => { let $var = Os(x); dispatch!($($body)*) },
}
};
($body: expr) => { $body };
}
unsafe fn chunk_unchecked(x: &[u8], n: usize, i: usize) -> &[u8] {
debug_assert!((i + 1) * n <= x.len());
let ptr = x.as_ptr().add(n * i);
core::slice::from_raw_parts(ptr, n)
}
unsafe fn chunk_mut_unchecked(x: &mut [u8], n: usize, i: usize) -> &mut [u8] {
debug_assert!((i + 1) * n <= x.len());
let ptr = x.as_mut_ptr().add(n * i);
core::slice::from_raw_parts_mut(ptr, n)
}
unsafe fn as_array(x: &[u8]) -> &[u8; 256] {
debug_assert_eq!(x.len(), 256);
&*(x.as_ptr() as *const [u8; 256])
}
fn div_ceil(x: usize, m: usize) -> usize {
(x + m - 1) / m
}
fn floor(x: usize, m: usize) -> usize {
x / m * m
}
fn vectorize<F: FnMut(usize)>(n: usize, bs: usize, mut f: F) {
for k in 0 .. n / bs {
for i in k * bs .. (k + 1) * bs {
f(i);
}
}
for i in floor(n, bs) .. n {
f(i);
}
}
/// Decoding error kind
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DecodeKind {
/// Invalid length
Length,
/// Invalid symbol
Symbol,
/// Non-zero trailing bits
Trailing,
/// Invalid padding length
Padding,
}
impl core::fmt::Display for DecodeKind {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let description = match self {
DecodeKind::Length => "invalid length",
DecodeKind::Symbol => "invalid symbol",
DecodeKind::Trailing => "non-zero trailing bits",
DecodeKind::Padding => "invalid padding length",
};
write!(f, "{}", description)
}
}
/// Decoding error
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct DecodeError {
/// Error position
///
/// This position is always a valid input position and represents the first encountered error.
pub position: usize,
/// Error kind
pub kind: DecodeKind,
}
#[cfg(feature = "std")]
impl std::error::Error for DecodeError {}
impl core::fmt::Display for DecodeError {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "{} at {}", self.kind, self.position)
}
}
/// Decoding error with partial result
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct DecodePartial {
/// Number of bytes read from input
///
/// This number does not exceed the error position: `read <= error.position`.
pub read: usize,
/// Number of bytes written to output
///
/// This number does not exceed the decoded length: `written <= decode_len(read)`.
pub written: usize,
/// Decoding error
pub error: DecodeError,
}
const INVALID: u8 = 128;
const IGNORE: u8 = 129;
const PADDING: u8 = 130;
fn order(msb: bool, n: usize, i: usize) -> usize {
if msb {
n - 1 - i
} else {
i
}
}
fn enc(bit: usize) -> usize {
match bit {
1 | 2 | 4 => 1,
3 | 6 => 3,
5 => 5,
_ => unreachable!(),
}
}
fn dec(bit: usize) -> usize {
enc(bit) * 8 / bit
}
fn encode_len<B: Static<usize>>(bit: B, len: usize) -> usize {
div_ceil(8 * len, bit.val())
}
fn encode_block<B: Static<usize>, M: Static<bool>>(
bit: B, msb: M, symbols: &[u8; 256], input: &[u8], output: &mut [u8],
) {
debug_assert!(input.len() <= enc(bit.val()));
debug_assert_eq!(output.len(), encode_len(bit, input.len()));
let bit = bit.val();
let msb = msb.val();
let mut x = 0u64;
for (i, input) in input.iter().enumerate() {
x |= u64::from(*input) << (8 * order(msb, enc(bit), i));
}
for (i, output) in output.iter_mut().enumerate() {
let y = x >> (bit * order(msb, dec(bit), i));
*output = symbols[y as usize % 256];
}
}
fn encode_mut<B: Static<usize>, M: Static<bool>>(
bit: B, msb: M, symbols: &[u8; 256], input: &[u8], output: &mut [u8],
) {
debug_assert_eq!(output.len(), encode_len(bit, input.len()));
let enc = enc(bit.val());
let dec = dec(bit.val());
let n = input.len() / enc;
let bs = match bit.val() {
5 => 2,
6 => 4,
_ => 1,
};
vectorize(n, bs, |i| {
let input = unsafe { chunk_unchecked(input, enc, i) };
let output = unsafe { chunk_mut_unchecked(output, dec, i) };
encode_block(bit, msb, symbols, input, output);
});
encode_block(bit, msb, symbols, &input[enc * n ..], &mut output[dec * n ..]);
}
// Fails if an input character does not translate to a symbol. The error is the
// lowest index of such character. The output is not written to.
fn decode_block<B: Static<usize>, M: Static<bool>>(
bit: B, msb: M, values: &[u8; 256], input: &[u8], output: &mut [u8],
) -> Result<(), usize> {
debug_assert!(output.len() <= enc(bit.val()));
debug_assert_eq!(input.len(), encode_len(bit, output.len()));
let bit = bit.val();
let msb = msb.val();
let mut x = 0u64;
for j in 0 .. input.len() {
let y = values[input[j] as usize];
check!(j, y < 1 << bit);
x |= u64::from(y) << (bit * order(msb, dec(bit), j));
}
for (j, output) in output.iter_mut().enumerate() {
*output = (x >> (8 * order(msb, enc(bit), j))) as u8;
}
Ok(())
}
// Fails if an input character does not translate to a symbol. The error `pos`
// is the lowest index of such character. The output is valid up to `pos / dec *
// enc` excluded.
fn decode_mut<B: Static<usize>, M: Static<bool>>(
bit: B, msb: M, values: &[u8; 256], input: &[u8], output: &mut [u8],
) -> Result<(), usize> {
debug_assert_eq!(input.len(), encode_len(bit, output.len()));
let enc = enc(bit.val());
let dec = dec(bit.val());
let n = input.len() / dec;
for i in 0 .. n {
let input = unsafe { chunk_unchecked(input, dec, i) };
let output = unsafe { chunk_mut_unchecked(output, enc, i) };
decode_block(bit, msb, values, input, output).map_err(|e| dec * i + e)?;
}
decode_block(bit, msb, values, &input[dec * n ..], &mut output[enc * n ..])
.map_err(|e| dec * n + e)
}
// Fails if there are non-zero trailing bits.
fn check_trail<B: Static<usize>, M: Static<bool>>(
bit: B, msb: M, ctb: bool, values: &[u8; 256], input: &[u8],
) -> Result<(), ()> {
if 8 % bit.val() == 0 || !ctb {
return Ok(());
}
let trail = bit.val() * input.len() % 8;
if trail == 0 {
return Ok(());
}
let mut mask = (1 << trail) - 1;
if !msb.val() {
mask <<= bit.val() - trail;
}
check!((), values[input[input.len() - 1] as usize] & mask == 0);
Ok(())
}
// Fails if the padding length is invalid. The error is the index of the first
// padding character.
fn check_pad<B: Static<usize>>(bit: B, values: &[u8; 256], input: &[u8]) -> Result<usize, usize> {
let bit = bit.val();
debug_assert_eq!(input.len(), dec(bit));
let is_pad = |x: &&u8| values[**x as usize] == PADDING;
let count = input.iter().rev().take_while(is_pad).count();
let len = input.len() - count;
check!(len, len > 0 && bit * len % 8 < bit);
Ok(len)
}
fn encode_base_len<B: Static<usize>>(bit: B, len: usize) -> usize {
encode_len(bit, len)
}
fn encode_base<B: Static<usize>, M: Static<bool>>(
bit: B, msb: M, symbols: &[u8; 256], input: &[u8], output: &mut [u8],
) {
debug_assert_eq!(output.len(), encode_base_len(bit, input.len()));
encode_mut(bit, msb, symbols, input, output);
}
fn encode_pad_len<B: Static<usize>, P: Static<Option<u8>>>(bit: B, pad: P, len: usize) -> usize {
match pad.val() {
None => encode_base_len(bit, len),
Some(_) => div_ceil(len, enc(bit.val())) * dec(bit.val()),
}
}
fn encode_pad<B: Static<usize>, M: Static<bool>, P: Static<Option<u8>>>(
bit: B, msb: M, symbols: &[u8; 256], spad: P, input: &[u8], output: &mut [u8],
) {
let pad = match spad.val() {
None => return encode_base(bit, msb, symbols, input, output),
Some(pad) => pad,
};
debug_assert_eq!(output.len(), encode_pad_len(bit, spad, input.len()));
let olen = encode_base_len(bit, input.len());
encode_base(bit, msb, symbols, input, &mut output[.. olen]);
for output in output.iter_mut().skip(olen) {
*output = pad;
}
}
fn encode_wrap_len<
'a,
B: Static<usize>,
P: Static<Option<u8>>,
W: Static<Option<(usize, &'a [u8])>>,
>(
bit: B, pad: P, wrap: W, ilen: usize,
) -> usize {
let olen = encode_pad_len(bit, pad, ilen);
match wrap.val() {
None => olen,
Some((col, end)) => olen + end.len() * div_ceil(olen, col),
}
}
fn encode_wrap_mut<
'a,
B: Static<usize>,
M: Static<bool>,
P: Static<Option<u8>>,
W: Static<Option<(usize, &'a [u8])>>,
>(
bit: B, msb: M, symbols: &[u8; 256], pad: P, wrap: W, input: &[u8], output: &mut [u8],
) {
let (col, end) = match wrap.val() {
None => return encode_pad(bit, msb, symbols, pad, input, output),
Some((col, end)) => (col, end),
};
debug_assert_eq!(output.len(), encode_wrap_len(bit, pad, wrap, input.len()));
debug_assert_eq!(col % dec(bit.val()), 0);
let col = col / dec(bit.val());
let enc = col * enc(bit.val());
let dec = col * dec(bit.val()) + end.len();
let olen = dec - end.len();
let n = input.len() / enc;
for i in 0 .. n {
let input = unsafe { chunk_unchecked(input, enc, i) };
let output = unsafe { chunk_mut_unchecked(output, dec, i) };
encode_base(bit, msb, symbols, input, &mut output[.. olen]);
output[olen ..].copy_from_slice(end);
}
if input.len() > enc * n {
let olen = dec * n + encode_pad_len(bit, pad, input.len() - enc * n);
encode_pad(bit, msb, symbols, pad, &input[enc * n ..], &mut output[dec * n .. olen]);
output[olen ..].copy_from_slice(end);
}
}
// Returns the longest valid input length and associated output length.
fn decode_wrap_len<B: Static<usize>, P: Static<bool>>(
bit: B, pad: P, len: usize,
) -> (usize, usize) {
let bit = bit.val();
if pad.val() {
(floor(len, dec(bit)), len / dec(bit) * enc(bit))
} else {
let trail = bit * len % 8;
(len - trail / bit, bit * len / 8)
}
}
// Fails with Length if length is invalid. The error is the largest valid
// length.
fn decode_pad_len<B: Static<usize>, P: Static<bool>>(
bit: B, pad: P, len: usize,
) -> Result<usize, DecodeError> {
let (ilen, olen) = decode_wrap_len(bit, pad, len);
check!(DecodeError { position: ilen, kind: DecodeKind::Length }, ilen == len);
Ok(olen)
}
// Fails with Length if length is invalid. The error is the largest valid
// length.
fn decode_base_len<B: Static<usize>>(bit: B, len: usize) -> Result<usize, DecodeError> {
decode_pad_len(bit, Bf, len)
}
// Fails with Symbol if an input character does not translate to a symbol. The
// error is the lowest index of such character.
// Fails with Trailing if there are non-zero trailing bits.
fn decode_base_mut<B: Static<usize>, M: Static<bool>>(
bit: B, msb: M, ctb: bool, values: &[u8; 256], input: &[u8], output: &mut [u8],
) -> Result<usize, DecodePartial> {
debug_assert_eq!(Ok(output.len()), decode_base_len(bit, input.len()));
let fail = |pos, kind| DecodePartial {
read: pos / dec(bit.val()) * dec(bit.val()),
written: pos / dec(bit.val()) * enc(bit.val()),
error: DecodeError { position: pos, kind },
};
decode_mut(bit, msb, values, input, output).map_err(|pos| fail(pos, DecodeKind::Symbol))?;
check_trail(bit, msb, ctb, values, input)
.map_err(|()| fail(input.len() - 1, DecodeKind::Trailing))?;
Ok(output.len())
}
// Fails with Symbol if an input character does not translate to a symbol. The
// error is the lowest index of such character.
// Fails with Padding if some padding length is invalid. The error is the index
// of the first padding character of the invalid padding.
// Fails with Trailing if there are non-zero trailing bits.
fn decode_pad_mut<B: Static<usize>, M: Static<bool>, P: Static<bool>>(
bit: B, msb: M, ctb: bool, values: &[u8; 256], pad: P, input: &[u8], output: &mut [u8],
) -> Result<usize, DecodePartial> {
if !pad.val() {
return decode_base_mut(bit, msb, ctb, values, input, output);
}
debug_assert_eq!(Ok(output.len()), decode_pad_len(bit, pad, input.len()));
let enc = enc(bit.val());
let dec = dec(bit.val());
let mut inpos = 0;
let mut outpos = 0;
let mut outend = output.len();
while inpos < input.len() {
match decode_base_mut(
bit,
msb,
ctb,
values,
&input[inpos ..],
&mut output[outpos .. outend],
) {
Ok(written) => {
if cfg!(debug_assertions) {
inpos = input.len();
}
outpos += written;
break;
}
Err(partial) => {
inpos += partial.read;
outpos += partial.written;
}
}
let inlen =
check_pad(bit, values, &input[inpos .. inpos + dec]).map_err(|pos| DecodePartial {
read: inpos,
written: outpos,
error: DecodeError { position: inpos + pos, kind: DecodeKind::Padding },
})?;
let outlen = decode_base_len(bit, inlen).unwrap();
let written = decode_base_mut(
bit,
msb,
ctb,
values,
&input[inpos .. inpos + inlen],
&mut output[outpos .. outpos + outlen],
)
.map_err(|partial| {
debug_assert_eq!(partial.read, 0);
debug_assert_eq!(partial.written, 0);
DecodePartial {
read: inpos,
written: outpos,
error: DecodeError {
position: inpos + partial.error.position,
kind: partial.error.kind,
},
}
})?;
debug_assert_eq!(written, outlen);
inpos += dec;
outpos += outlen;
outend -= enc - outlen;
}
debug_assert_eq!(inpos, input.len());
debug_assert_eq!(outpos, outend);
Ok(outend)
}
fn skip_ignore(values: &[u8; 256], input: &[u8], mut inpos: usize) -> usize {
while inpos < input.len() && values[input[inpos] as usize] == IGNORE {
inpos += 1;
}
inpos
}
// Returns next input and output position.
// Fails with Symbol if an input character does not translate to a symbol. The
// error is the lowest index of such character.
// Fails with Padding if some padding length is invalid. The error is the index
// of the first padding character of the invalid padding.
// Fails with Trailing if there are non-zero trailing bits.
fn decode_wrap_block<B: Static<usize>, M: Static<bool>, P: Static<bool>>(
bit: B, msb: M, ctb: bool, values: &[u8; 256], pad: P, input: &[u8], output: &mut [u8],
) -> Result<(usize, usize), DecodeError> {
let dec = dec(bit.val());
let mut buf = [0u8; 8];
let mut shift = [0usize; 8];
let mut bufpos = 0;
let mut inpos = 0;
while bufpos < dec {
inpos = skip_ignore(values, input, inpos);
if inpos == input.len() {
break;
}
shift[bufpos] = inpos;
buf[bufpos] = input[inpos];
bufpos += 1;
inpos += 1;
}
let olen = decode_pad_len(bit, pad, bufpos).map_err(|mut e| {
e.position = shift[e.position];
e
})?;
let written = decode_pad_mut(bit, msb, ctb, values, pad, &buf[.. bufpos], &mut output[.. olen])
.map_err(|partial| {
debug_assert_eq!(partial.read, 0);
debug_assert_eq!(partial.written, 0);
DecodeError { position: shift[partial.error.position], kind: partial.error.kind }
})?;
Ok((inpos, written))
}
// Fails with Symbol if an input character does not translate to a symbol. The
// error is the lowest index of such character.
// Fails with Padding if some padding length is invalid. The error is the index
// of the first padding character of the invalid padding.
// Fails with Trailing if there are non-zero trailing bits.
// Fails with Length if input length (without ignored characters) is invalid.
#[allow(clippy::too_many_arguments)]
fn decode_wrap_mut<B: Static<usize>, M: Static<bool>, P: Static<bool>, I: Static<bool>>(
bit: B, msb: M, ctb: bool, values: &[u8; 256], pad: P, has_ignore: I, input: &[u8],
output: &mut [u8],
) -> Result<usize, DecodePartial> {
if !has_ignore.val() {
return decode_pad_mut(bit, msb, ctb, values, pad, input, output);
}
debug_assert_eq!(output.len(), decode_wrap_len(bit, pad, input.len()).1);
let mut inpos = 0;
let mut outpos = 0;
while inpos < input.len() {
let (inlen, outlen) = decode_wrap_len(bit, pad, input.len() - inpos);
match decode_pad_mut(
bit,
msb,
ctb,
values,
pad,
&input[inpos .. inpos + inlen],
&mut output[outpos .. outpos + outlen],
) {
Ok(written) => {
inpos += inlen;
outpos += written;
break;
}
Err(partial) => {
inpos += partial.read;
outpos += partial.written;
}
}
let (ipos, opos) =
decode_wrap_block(bit, msb, ctb, values, pad, &input[inpos ..], &mut output[outpos ..])
.map_err(|mut error| {
error.position += inpos;
DecodePartial { read: inpos, written: outpos, error }
})?;
inpos += ipos;
outpos += opos;
}
let inpos = skip_ignore(values, input, inpos);
if inpos == input.len() {
Ok(outpos)
} else {
Err(DecodePartial {
read: inpos,
written: outpos,
error: DecodeError { position: inpos, kind: DecodeKind::Length },
})
}
}
/// Order in which bits are read from a byte
///
/// The base-conversion encoding is always little-endian. This means that the least significant
/// **byte** is always first. However, we can still choose whether, within a byte, this is the most
/// significant or the least significant **bit** that is first. If the terminology is confusing,
/// testing on an asymmetrical example should be enough to choose the correct value.
///
/// # Examples
///
/// In the following example, we can see that a base with the `MostSignificantFirst` bit-order has
/// the most significant bit first in the encoded output. In particular, the output is in the same
/// order as the bits in the byte. The opposite happens with the `LeastSignificantFirst` bit-order.
/// The least significant bit is first and the output is in the reverse order.
///
/// ```rust
/// use data_encoding::{BitOrder, Specification};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("01");
/// spec.bit_order = BitOrder::MostSignificantFirst; // default
/// let msb = spec.encoding().unwrap();
/// spec.bit_order = BitOrder::LeastSignificantFirst;
/// let lsb = spec.encoding().unwrap();
/// assert_eq!(msb.encode(&[0b01010011]), "01010011");
/// assert_eq!(lsb.encode(&[0b01010011]), "11001010");
/// ```
///
/// # Features
///
/// Requires the `alloc` feature.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg(feature = "alloc")]
pub enum BitOrder {
/// Most significant bit first
///
/// This is the most common and most intuitive bit-order. In particular, this is the bit-order
/// used by [RFC4648] and thus the usual hexadecimal, base64, base32, base64url, and base32hex
/// encodings. This is the default bit-order when [specifying](struct.Specification.html) a
/// base.
///
MostSignificantFirst,
/// Least significant bit first
///
/// # Examples
///
/// DNSCurve [base32] uses least significant bit first:
///
/// ```rust
/// use data_encoding::BASE32_DNSCURVE;
/// assert_eq!(BASE32_DNSCURVE.encode(&[0x64, 0x88]), "4321");
/// assert_eq!(BASE32_DNSCURVE.decode(b"4321").unwrap(), vec![0x64, 0x88]);
/// ```
///
/// [base32]: constant.BASE32_DNSCURVE.html
LeastSignificantFirst,
}
#[cfg(feature = "alloc")]
use crate::BitOrder::*;
#[doc(hidden)]
#[cfg(feature = "alloc")]
pub type InternalEncoding = Cow<'static, [u8]>;
#[doc(hidden)]
#[cfg(not(feature = "alloc"))]
pub type InternalEncoding = &'static [u8];
/// Base-conversion encoding
///
/// See [Specification](struct.Specification.html) for technical details or how to define a new one.
// Required fields:
// 0 - 256 (256) symbols
// 256 - 512 (256) values
// 512 - 513 ( 1) padding
// 513 - 514 ( 1) reserved(3),ctb(1),msb(1),bit(3)
// Optional fields:
// 514 - 515 ( 1) width
// 515 - * ( N) separator
// Invariants:
// - symbols is 2^bit unique characters repeated 2^(8-bit) times
// - values[128 ..] are INVALID
// - values[0 .. 128] are either INVALID, IGNORE, PADDING, or < 2^bit
// - padding is either < 128 or INVALID
// - values[padding] is PADDING if padding < 128
// - values and symbols are inverse
// - ctb is true if 8 % bit == 0
// - width is present if there is x such that values[x] is IGNORE
// - width % dec(bit) == 0
// - for all x in separator values[x] is IGNORE
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Encoding(pub InternalEncoding);
/// How to translate characters when decoding
///
/// The order matters. The first character of the `from` field is translated to the first character
/// of the `to` field. The second to the second. Etc.
///
/// See [Specification](struct.Specification.html) for more information.
///
/// # Features
///
/// Requires the `alloc` feature.
#[derive(Debug, Clone)]
#[cfg(feature = "alloc")]
pub struct Translate {
/// Characters to translate from
pub from: String,
/// Characters to translate to
pub to: String,
}
/// How to wrap the output when encoding
///
/// See [Specification](struct.Specification.html) for more information.
///
/// # Features
///
/// Requires the `alloc` feature.
#[derive(Debug, Clone)]
#[cfg(feature = "alloc")]
pub struct Wrap {
/// Wrapping width
///
/// Must be a multiple of:
///
/// - 8 for a bit-width of 1 (binary), 3 (octal), and 5 (base32)
/// - 4 for a bit-width of 2 (base4) and 6 (base64)
/// - 2 for a bit-width of 4 (hexadecimal)
///
/// Wrapping is disabled if null.
pub width: usize,
/// Wrapping characters
///
/// Wrapping is disabled if empty.
pub separator: String,
}
/// Base-conversion specification
///
/// It is possible to define custom encodings given a specification. To do so, it is important to
/// understand the theory first.
///
/// # Theory
///
/// Each subsection has an equivalent subsection in the [Practice](#practice) section.
///
/// ## Basics
///
/// The main idea of a [base-conversion] encoding is to see `[u8]` as numbers written in
/// little-endian base256 and convert them in another little-endian base. For performance reasons,
/// this crate restricts this other base to be of size 2 (binary), 4 (base4), 8 (octal), 16
/// (hexadecimal), 32 (base32), or 64 (base64). The converted number is written as `[u8]` although
/// it doesn't use all the 256 possible values of `u8`. This crate encodes to ASCII, so only values
/// smaller than 128 are allowed.
///
/// More precisely, we need the following elements:
///
/// - The bit-width N: 1 for binary, 2 for base4, 3 for octal, 4 for hexadecimal, 5 for base32, and
/// 6 for base64
/// - The [bit-order](enum.BitOrder.html): most or least significant bit first
/// - The symbols function S from [0, 2<sup>N</sup>) (called values and written `uN`) to symbols
/// (represented as `u8` although only ASCII symbols are allowed, i.e. smaller than 128)
/// - The values partial function V from ASCII to [0, 2<sup>N</sup>), i.e. from `u8` to `uN`
/// - Whether trailing bits are checked: trailing bits are leading zeros in theory, but since
/// numbers are little-endian they come last
///
/// For the encoding to be correct (i.e. encoding then decoding gives back the initial input),
/// V(S(i)) must be defined and equal to i for all i in [0, 2<sup>N</sup>). For the encoding to be
/// [canonical][canonical] (i.e. different inputs decode to different outputs, or equivalently,
/// decoding then encoding gives back the initial input), trailing bits must be checked and if V(i)
/// is defined then S(V(i)) is equal to i for all i.
///
/// Encoding and decoding are given by the following pipeline:
///
/// ```text
/// [u8] <--1--> [[bit; 8]] <--2--> [[bit; N]] <--3--> [uN] <--4--> [u8]
/// 1: Map bit-order between each u8 and [bit; 8]
/// 2: Base conversion between base 2^8 and base 2^N (check trailing bits)
/// 3: Map bit-order between each [bit; N] and uN
/// 4: Map symbols/values between each uN and u8 (values must be defined)
/// ```
///
/// ## Extensions
///
/// All these extensions make the encoding not canonical.
///
/// ### Padding
///
/// Padding is useful if the following conditions are met:
///
/// - the bit-width is 3 (octal), 5 (base32), or 6 (base64)
/// - the length of the data to encode is not known in advance
/// - the data must be sent without buffering
///
/// Bases for which the bit-width N does not divide 8 may not concatenate encoded data. This comes
/// from the fact that it is not possible to make the difference between trailing bits and encoding
/// bits. Padding solves this issue by adding a new character to discriminate between trailing bits
/// and encoding bits. The idea is to work by blocks of lcm(8, N) bits, where lcm(8, N) is the least
/// common multiple of 8 and N. When such block is not complete, it is padded.
///
/// To preserve correctness, the padding character must not be a symbol.
///
/// ### Ignore characters when decoding
///
/// Ignoring characters when decoding is useful if after encoding some characters are added for
/// convenience or any other reason (like wrapping). In that case we want to first ignore thoses
/// characters before decoding.
///
/// To preserve correctness, ignored characters must not contain symbols or the padding character.
///
/// ### Wrap output when encoding
///
/// Wrapping output when encoding is useful if the output is meant to be printed in a document where
/// width is limited (typically 80-columns documents). In that case, the wrapping width and the
/// wrapping separator have to be defined.
///
/// To preserve correctness, the wrapping separator characters must be ignored (see previous
/// subsection). As such, wrapping separator characters must also not contain symbols or the padding
/// character.
///
/// ### Translate characters when decoding
///
/// Translating characters when decoding is useful when encoded data may be copied by a humain
/// instead of a machine. Humans tend to confuse some characters for others. In that case we want to
/// translate those characters before decoding.
///
/// To preserve correctness, the characters we translate _from_ must not contain symbols or the
/// padding character, and the characters we translate _to_ must only contain symbols or the padding
/// character.
///
/// # Practice
///
/// ## Basics
///
/// ```rust
/// use data_encoding::{Encoding, Specification};
/// fn make_encoding(symbols: &str) -> Encoding {
/// let mut spec = Specification::new();
/// spec.symbols.push_str(symbols);
/// spec.encoding().unwrap()
/// }
/// let binary = make_encoding("01");
/// let octal = make_encoding("01234567");
/// let hexadecimal = make_encoding("0123456789abcdef");
/// assert_eq!(binary.encode(b"Bit"), "010000100110100101110100");
/// assert_eq!(octal.encode(b"Bit"), "20464564");
/// assert_eq!(hexadecimal.encode(b"Bit"), "426974");
/// ```
///
/// The `binary` base has 2 symbols `0` and `1` with value 0 and 1 respectively. The `octal` base
/// has 8 symbols `0` to `7` with value 0 to 7. The `hexadecimal` base has 16 symbols `0` to `9` and
/// `a` to `f` with value 0 to 15. The following diagram gives the idea of how encoding works in the
/// previous example (note that we can actually write such diagram only because the bit-order is
/// most significant first):
///
/// ```text
/// [ octal] | 2 : 0 : 4 : 6 : 4 : 5 : 6 : 4 |
/// [ 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|
/// [hexadecimal] | 4 : 2 | 6 : 9 | 7 : 4 |
/// ^-- LSB ^-- MSB
/// ```
///
/// Note that in theory, these little-endian numbers are read from right to left (the most
/// significant bit is at the right). Since leading zeros are meaningless (in our usual decimal
/// notation 0123 is the same as 123), it explains why trailing bits must be zero. Trailing bits may
/// occur when the bit-width of a base does not divide 8. Only binary, base4, and hexadecimal don't
/// have trailing bits issues. So let's consider octal and base64, which have trailing bits in
/// similar circumstances:
///
/// ```rust
/// use data_encoding::{Specification, BASE64_NOPAD};
/// let octal = {
/// let mut spec = Specification::new();
/// spec.symbols.push_str("01234567");
/// spec.encoding().unwrap()
/// };
/// assert_eq!(BASE64_NOPAD.encode(b"B"), "Qg");
/// assert_eq!(octal.encode(b"B"), "204");
/// ```
///
/// We have the following diagram, where the base64 values are written between parentheses:
///
/// ```text
/// [base64] | Q(16) : g(32) : [has 4 zero trailing bits]
/// [ octal] | 2 : 0 : 4 : [has 1 zero trailing bit ]
/// |0 1 0 0 0 0 1 0|0 0 0 0
/// [ ascii] | B |
/// ^-^-^-^-- leading zeros / trailing bits
/// ```
///
/// ## Extensions
///
/// ### Padding
///
/// For octal and base64, lcm(8, 3) == lcm(8, 6) == 24 bits or 3 bytes. For base32, lcm(8, 5) is 40
/// bits or 5 bytes. Let's consider octal and base64:
///
/// ```rust
/// use data_encoding::{Specification, BASE64};
/// let octal = {
/// let mut spec = Specification::new();
/// spec.symbols.push_str("01234567");
/// spec.padding = Some('=');
/// spec.encoding().unwrap()
/// };
/// // We start encoding but we only have "B" for now.
/// assert_eq!(BASE64.encode(b"B"), "Qg==");
/// assert_eq!(octal.encode(b"B"), "204=====");
/// // Now we have "it".
/// assert_eq!(BASE64.encode(b"it"), "aXQ=");
/// assert_eq!(octal.encode(b"it"), "322720==");
/// // By concatenating everything, we may decode the original data.
/// assert_eq!(BASE64.decode(b"Qg==aXQ=").unwrap(), b"Bit");
/// assert_eq!(octal.decode(b"204=====322720==").unwrap(), b"Bit");
/// ```
///
/// We have the following diagrams:
///
/// ```text
/// [base64] | Q(16) : g(32) : = : = |
/// [ octal] | 2 : 0 : 4 : = : = : = : = : = |
/// |0 1 0 0 0 0 1 0|. . . . . . . .|. . . . . . . .|
/// [ ascii] | B | end of block aligned --^
/// ^-- beginning of block aligned
///
/// [base64] | a(26) : X(23) : Q(16) : = |
/// [ octal] | 3 : 2 : 2 : 7 : 2 : 0 : = : = |
/// |0 1 1 0 1 0 0 1|0 1 1 1 0 1 0 0|. . . . . . . .|
/// [ ascii] | i | t |
/// ```
///
/// ### Ignore characters when decoding
///
/// The typical use-case is to ignore newlines (`\r` and `\n`). But to keep the example small, we
/// will ignore spaces.
///
/// ```rust
/// let mut spec = data_encoding::HEXLOWER.specification();
/// spec.ignore.push_str(" \t");
/// let base = spec.encoding().unwrap();
/// assert_eq!(base.decode(b"42 69 74"), base.decode(b"426974"));
/// ```
///
/// ### Wrap output when encoding
///
/// The typical use-case is to wrap after 64 or 76 characters with a newline (`\r\n` or `\n`). But
/// to keep the example small, we will wrap after 8 characters with a space.
///
/// ```rust
/// let mut spec = data_encoding::BASE64.specification();
/// spec.wrap.width = 8;
/// spec.wrap.separator.push_str(" ");
/// let base64 = spec.encoding().unwrap();
/// assert_eq!(base64.encode(b"Hey you"), "SGV5IHlv dQ== ");
/// ```
///
/// Note that the output always ends with the separator.
///
/// ### Translate characters when decoding
///
/// The typical use-case is to translate lowercase to uppercase or reciprocally, but it is also used
/// for letters that look alike, like `O0` or `Il1`. Let's illustrate both examples.
///
/// ```rust
/// let mut spec = data_encoding::HEXLOWER.specification();
/// spec.translate.from.push_str("ABCDEFOIl");
/// spec.translate.to.push_str("abcdef011");
/// let base = spec.encoding().unwrap();
/// assert_eq!(base.decode(b"BOIl"), base.decode(b"b011"));
/// ```
///
/// # Features
///
/// Requires the `alloc` feature.
///
#[derive(Debug, Clone)]
#[cfg(feature = "alloc")]
pub struct Specification {
/// Symbols
///
/// The number of symbols must be 2, 4, 8, 16, 32, or 64. Symbols must be ASCII characters
/// (smaller than 128) and they must be unique.
pub symbols: String,
/// Bit-order
///
/// The default is to use most significant bit first since it is the most common.
pub bit_order: BitOrder,
/// Check trailing bits
///
/// The default is to check trailing bits. This field is ignored when unnecessary (i.e. for
/// base2, base4, and base16).
pub check_trailing_bits: bool,
/// Padding
///
/// The default is to not use padding. The padding character must be ASCII and must not be a
/// symbol.
pub padding: Option<char>,
/// Characters to ignore when decoding
///
/// The default is to not ignore characters when decoding. The characters to ignore must be
/// ASCII and must not be symbols or the padding character.
pub ignore: String,
/// How to wrap the output when encoding
///
/// The default is to not wrap the output when encoding. The wrapping characters must be ASCII
/// and must not be symbols or the padding character.
pub wrap: Wrap,
/// How to translate characters when decoding
///
/// The default is to not translate characters when decoding. The characters to translate from
/// must be ASCII and must not have already been assigned a semantics. The characters to
/// translate to must be ASCII and must have been assigned a semantics (symbol, padding
/// character, or ignored character).
pub translate: Translate,
}
#[cfg(feature = "alloc")]
impl Default for Specification {
fn default() -> Self {
Self::new()
}
}
impl Encoding {
fn sym(&self) -> &[u8; 256] {
unsafe { as_array(&self.0[0 .. 256]) }
}
fn val(&self) -> &[u8; 256] {
unsafe { as_array(&self.0[256 .. 512]) }
}
fn pad(&self) -> Option<u8> {
if self.0[512] < 128 {
Some(self.0[512])
} else {
None
}
}
fn ctb(&self) -> bool {
self.0[513] & 0x10 != 0
}
fn msb(&self) -> bool {
self.0[513] & 0x8 != 0
}
fn bit(&self) -> usize {
(self.0[513] & 0x7) as usize
}
fn wrap(&self) -> Option<(usize, &[u8])> {
if self.0.len() <= 515 {
return None;
}
Some((self.0[514] as usize, &self.0[515 ..]))
}
fn has_ignore(&self) -> bool {
self.0.len() >= 515
}
/// Returns the encoded length of an input of length `len`
///
/// See [`encode_mut`] for when to use it.
///
/// [`encode_mut`]: struct.Encoding.html#method.encode_mut
pub fn encode_len(&self, len: usize) -> usize {
dispatch! {
let bit: usize = self.bit();
let pad: Option<u8> = self.pad();
let wrap: Option<(usize, &[u8])> = self.wrap();
encode_wrap_len(bit, pad, wrap, len)
}
}
/// Encodes `input` in `output`
///
/// # Panics
///
/// Panics if the `output` length does not match the result of [`encode_len`] for the `input`
/// length.
///
/// # Examples
///
/// ```rust
/// use data_encoding::BASE64;
/// # let mut buffer = vec![0; 100];
/// let input = b"Hello world";
/// let output = &mut buffer[0 .. BASE64.encode_len(input.len())];
/// BASE64.encode_mut(input, output);
/// assert_eq!(output, b"SGVsbG8gd29ybGQ=");
/// ```
///
/// [`encode_len`]: struct.Encoding.html#method.encode_len
#[allow(clippy::cognitive_complexity)]
pub fn encode_mut(&self, input: &[u8], output: &mut [u8]) {
assert_eq!(output.len(), self.encode_len(input.len()));
dispatch! {
let bit: usize = self.bit();
let msb: bool = self.msb();
let pad: Option<u8> = self.pad();
let wrap: Option<(usize, &[u8])> = self.wrap();
encode_wrap_mut(bit, msb, self.sym(), pad, wrap, input, output)
}
}
/// Appends the encoding of `input` to `output`
///
/// # Examples
///
/// ```rust
/// use data_encoding::BASE64;
/// # let mut buffer = vec![0; 100];
/// let input = b"Hello world";
/// let mut output = "Result: ".to_string();
/// BASE64.encode_append(input, &mut output);
/// assert_eq!(output, "Result: SGVsbG8gd29ybGQ=");
/// ```
///
/// # Features
///
/// Requires the `alloc` feature.
#[cfg(feature = "alloc")]
pub fn encode_append(&self, input: &[u8], output: &mut String) {
let output = unsafe { output.as_mut_vec() };
let output_len = output.len();
output.resize(output_len + self.encode_len(input.len()), 0u8);
self.encode_mut(input, &mut output[output_len ..]);
}
/// Returns encoded `input`
///
/// # Examples
///
/// ```rust
/// use data_encoding::BASE64;
/// assert_eq!(BASE64.encode(b"Hello world"), "SGVsbG8gd29ybGQ=");
/// ```
///
/// # Features
///
/// Requires the `alloc` feature.
#[cfg(feature = "alloc")]
pub fn encode(&self, input: &[u8]) -> String {
let mut output = vec![0u8; self.encode_len(input.len())];
self.encode_mut(input, &mut output);
unsafe { String::from_utf8_unchecked(output) }
}
/// Returns the decoded length of an input of length `len`
///
/// See [`decode_mut`] for when to use it.
///
/// # Errors
///
/// Returns an error if `len` is invalid. The error kind is [`Length`] and the [position] is the
/// greatest valid input length.
///
/// [`decode_mut`]: struct.Encoding.html#method.decode_mut
/// [`Length`]: enum.DecodeKind.html#variant.Length
/// [position]: struct.DecodeError.html#structfield.position
pub fn decode_len(&self, len: usize) -> Result<usize, DecodeError> {
let (ilen, olen) = dispatch! {
let bit: usize = self.bit();
let pad: bool = self.pad().is_some();
decode_wrap_len(bit, pad, len)
};
check!(
DecodeError { position: ilen, kind: DecodeKind::Length },
self.has_ignore() || len == ilen
);
Ok(olen)
}
/// Decodes `input` in `output`
///
/// Returns the length of the decoded output. This length may be smaller than the output length
/// if the input contained padding or ignored characters. The output bytes after the returned
/// length are not initialized and should not be read.
///
/// # Panics
///
/// Panics if the `output` length does not match the result of [`decode_len`] for the `input`
/// length. Also panics if `decode_len` fails for the `input` length.
///
/// # Errors
///
/// Returns an error if `input` is invalid. See [`decode`] for more details. The are two
/// differences though:
///
/// - [`Length`] may be returned only if the encoding allows ignored characters, because
/// otherwise this is already checked by [`decode_len`].
/// - The [`read`] first bytes of the input have been successfully decoded to the [`written`]
/// first bytes of the output.
///
/// # Examples
///
/// ```rust
/// use data_encoding::BASE64;
/// # let mut buffer = vec![0; 100];
/// let input = b"SGVsbA==byB3b3JsZA==";
/// let output = &mut buffer[0 .. BASE64.decode_len(input.len()).unwrap()];
/// let len = BASE64.decode_mut(input, output).unwrap();
/// assert_eq!(&output[0 .. len], b"Hello world");
/// ```
///
/// [`decode_len`]: struct.Encoding.html#method.decode_len
/// [`decode`]: struct.Encoding.html#method.decode
/// [`Length`]: enum.DecodeKind.html#variant.Length
/// [`read`]: struct.DecodePartial.html#structfield.read
/// [`written`]: struct.DecodePartial.html#structfield.written
#[allow(clippy::cognitive_complexity)]
pub fn decode_mut(&self, input: &[u8], output: &mut [u8]) -> Result<usize, DecodePartial> {
assert_eq!(Ok(output.len()), self.decode_len(input.len()));
dispatch! {
let bit: usize = self.bit();
let msb: bool = self.msb();
let pad: bool = self.pad().is_some();
let has_ignore: bool = self.has_ignore();
decode_wrap_mut(bit, msb, self.ctb(), self.val(), pad, has_ignore,
input, output)
}
}
/// Returns decoded `input`
///
/// # Errors
///
/// Returns an error if `input` is invalid. The error kind can be:
///
/// - [`Length`] if the input length is invalid. The [position] is the greatest valid input
/// length.
/// - [`Symbol`] if the input contains an invalid character. The [position] is the first invalid
/// character.
/// - [`Trailing`] if the input has non-zero trailing bits. This is only possible if the
/// encoding checks trailing bits. The [position] is the first character containing non-zero
/// trailing bits.
/// - [`Padding`] if the input has an invalid padding length. This is only possible if the
/// encoding uses padding. The [position] is the first padding character of the first padding
/// of invalid length.
///
/// # Examples
///
/// ```rust
/// use data_encoding::BASE64;
/// assert_eq!(BASE64.decode(b"SGVsbA==byB3b3JsZA==").unwrap(), b"Hello world");
/// ```
///
/// # Features
///
/// Requires the `alloc` feature.
///
/// [`Length`]: enum.DecodeKind.html#variant.Length
/// [`Symbol`]: enum.DecodeKind.html#variant.Symbol
/// [`Trailing`]: enum.DecodeKind.html#variant.Trailing
/// [`Padding`]: enum.DecodeKind.html#variant.Padding
/// [position]: struct.DecodeError.html#structfield.position
#[cfg(feature = "alloc")]
pub fn decode(&self, input: &[u8]) -> Result<Vec<u8>, DecodeError> {
let mut output = vec![0u8; self.decode_len(input.len())?];
let len = self.decode_mut(input, &mut output).map_err(|partial| partial.error)?;
output.truncate(len);
Ok(output)
}
/// Returns the bit-width
pub fn bit_width(&self) -> usize {
self.bit()
}
/// Returns whether the encoding is canonical
///
/// An encoding is not canonical if one of the following conditions holds:
///
/// - trailing bits are not checked
/// - padding is used
/// - characters are ignored
/// - characters are translated
pub fn is_canonical(&self) -> bool {
if !self.ctb() {
return false;
}
let bit = self.bit();
let sym = self.sym();
let val = self.val();
for i in 0 .. 256 {
if val[i] == INVALID {
continue;
}
if val[i] >= 1 << bit {
return false;
}
if sym[val[i] as usize] != i as u8 {
return false;
}
}
true
}
/// Returns the encoding specification
///
/// # Features
///
/// Requires the `alloc` feature.
#[cfg(feature = "alloc")]
pub fn specification(&self) -> Specification {
let mut specification = Specification::new();
specification
.symbols
.push_str(core::str::from_utf8(&self.sym()[0 .. 1 << self.bit()]).unwrap());
specification.bit_order =
if self.msb() { MostSignificantFirst } else { LeastSignificantFirst };
specification.check_trailing_bits = self.ctb();
if let Some(pad) = self.pad() {
specification.padding = Some(pad as char);
}
for i in 0 .. 128u8 {
if self.val()[i as usize] != IGNORE {
continue;
}
specification.ignore.push(i as char);
}
if let Some((col, end)) = self.wrap() {
specification.wrap.width = col;
specification.wrap.separator = core::str::from_utf8(end).unwrap().to_owned();
}
for i in 0 .. 128u8 {
let canonical = if self.val()[i as usize] < 1 << self.bit() {
self.sym()[self.val()[i as usize] as usize]
} else if self.val()[i as usize] == PADDING {
self.pad().unwrap()
} else {
continue;
};
if i == canonical {
continue;
}
specification.translate.from.push(i as char);
specification.translate.to.push(canonical as char);
}
specification
}
#[doc(hidden)]
pub const fn internal_new(implementation: &'static [u8]) -> Encoding {
#[cfg(feature = "alloc")]
let encoding = Encoding(Cow::Borrowed(implementation));
#[cfg(not(feature = "alloc"))]
let encoding = Encoding(implementation);
encoding
}
#[doc(hidden)]
pub fn internal_implementation(&self) -> &[u8] {
&self.0
}
}
#[derive(Debug, Copy, Clone)]
#[cfg(feature = "alloc")]
enum SpecificationErrorImpl {
BadSize,
NotAscii,
Duplicate(u8),
ExtraPadding,
WrapLength,
WrapWidth(u8),
FromTo,
Undefined(u8),
}
#[cfg(feature = "alloc")]
use crate::SpecificationErrorImpl::*;
/// Specification error
///
/// # Features
///
/// Requires the `alloc` feature.
#[derive(Debug, Copy, Clone)]
#[cfg(feature = "alloc")]
pub struct SpecificationError(SpecificationErrorImpl);
#[cfg(feature = "alloc")]
impl core::fmt::Display for SpecificationError {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
match self.0 {
BadSize => write!(f, "invalid number of symbols"),
NotAscii => write!(f, "non-ascii character"),
Duplicate(c) => write!(f, "{:?} has conflicting definitions", c as char),
ExtraPadding => write!(f, "unnecessary padding"),
WrapLength => write!(f, "invalid wrap width or separator length"),
WrapWidth(x) => write!(f, "wrap width not a multiple of {}", x),
FromTo => write!(f, "translate from/to length mismatch"),
Undefined(c) => write!(f, "{:?} is undefined", c as char),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for SpecificationError {
fn description(&self) -> &str {
match self.0 {
BadSize => "invalid number of symbols",
NotAscii => "non-ascii character",
Duplicate(_) => "conflicting definitions",
ExtraPadding => "unnecessary padding",
WrapLength => "invalid wrap width or separator length",
WrapWidth(_) => "wrap width not a multiple",
FromTo => "translate from/to length mismatch",
Undefined(_) => "undefined character",
}
}
}
#[cfg(feature = "alloc")]
impl Specification {
/// Returns a default specification
pub fn new() -> Specification {
Specification {
symbols: String::new(),
bit_order: MostSignificantFirst,
check_trailing_bits: true,
padding: None,
ignore: String::new(),
wrap: Wrap { width: 0, separator: String::new() },
translate: Translate { from: String::new(), to: String::new() },
}
}
/// Returns the specified encoding
///
/// # Errors
///
/// Returns an error if the specification is invalid.
pub fn encoding(&self) -> Result<Encoding, SpecificationError> {
let symbols = self.symbols.as_bytes();
let bit: usize = match symbols.len() {
2 => 1,
4 => 2,
8 => 3,
16 => 4,
32 => 5,
64 => 6,
_ => return Err(SpecificationError(BadSize)),
};
let mut values = [INVALID; 128];
let set = |v: &mut [u8; 128], i: u8, x: u8| {
check!(SpecificationError(NotAscii), i < 128);
if v[i as usize] == x {
return Ok(());
}
check!(SpecificationError(Duplicate(i)), v[i as usize] == INVALID);
v[i as usize] = x;
Ok(())
};
for (v, symbols) in symbols.iter().enumerate() {
set(&mut values, *symbols, v as u8)?;
}
let msb = self.bit_order == MostSignificantFirst;
let ctb = self.check_trailing_bits || 8 % bit == 0;
let pad = match self.padding {
None => None,
Some(pad) => {
check!(SpecificationError(ExtraPadding), 8 % bit != 0);
check!(SpecificationError(NotAscii), pad.len_utf8() == 1);
set(&mut values, pad as u8, PADDING)?;
Some(pad as u8)
}
};
for i in self.ignore.bytes() {
set(&mut values, i, IGNORE)?;
}
let wrap = if self.wrap.separator.is_empty() || self.wrap.width == 0 {
None
} else {
Some((self.wrap.width, self.wrap.separator.as_bytes()))
};
if let Some((col, end)) = wrap {
check!(SpecificationError(WrapLength), col < 256 && end.len() < 256);
check!(SpecificationError(WrapWidth(dec(bit) as u8)), col % dec(bit) == 0);
for i in end.iter() {
set(&mut values, *i, IGNORE)?;
}
}
let from = self.translate.from.as_bytes();
let to = self.translate.to.as_bytes();
check!(SpecificationError(FromTo), from.len() == to.len());
for i in 0 .. from.len() {
check!(SpecificationError(NotAscii), to[i] < 128);
let v = values[to[i] as usize];
check!(SpecificationError(Undefined(to[i])), v != INVALID);
set(&mut values, from[i], v)?;
}
let mut encoding = Vec::new();
for _ in 0 .. 256 / symbols.len() {
encoding.extend_from_slice(symbols);
}
encoding.extend_from_slice(&values);
encoding.extend_from_slice(&[INVALID; 128]);
match pad {
None => encoding.push(INVALID),
Some(pad) => encoding.push(pad),
}
encoding.push(bit as u8);
if msb {
encoding[513] |= 0x08;
}
if ctb {
encoding[513] |= 0x10;
}
if let Some((col, end)) = wrap {
encoding.push(col as u8);
encoding.extend_from_slice(end);
} else if values.contains(&IGNORE) {
encoding.push(0);
}
Ok(Encoding(Cow::Owned(encoding)))
}
}
/// Lowercase hexadecimal encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, HEXLOWER};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("0123456789abcdef");
/// assert_eq!(HEXLOWER, spec.encoding().unwrap());
/// ```
///
/// # Examples
///
/// ```rust
/// use data_encoding::HEXLOWER;
/// let deadbeef = vec![0xde, 0xad, 0xbe, 0xef];
/// assert_eq!(HEXLOWER.decode(b"deadbeef").unwrap(), deadbeef);
/// assert_eq!(HEXLOWER.encode(&deadbeef), "deadbeef");
/// ```
pub const HEXLOWER: Encoding = Encoding::internal_new(HEXLOWER_IMPL);
const HEXLOWER_IMPL: &[u8] = &[
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100,
101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100,
101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 97, 98, 99, 100, 101, 102, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 28,
];
/// Lowercase hexadecimal encoding with case-insensitive decoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, HEXLOWER_PERMISSIVE};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("0123456789abcdef");
/// spec.translate.from.push_str("ABCDEF");
/// spec.translate.to.push_str("abcdef");
/// assert_eq!(HEXLOWER_PERMISSIVE, spec.encoding().unwrap());
/// ```
///
/// # Examples
///
/// ```rust
/// use data_encoding::HEXLOWER_PERMISSIVE;
/// let deadbeef = vec![0xde, 0xad, 0xbe, 0xef];
/// assert_eq!(HEXLOWER_PERMISSIVE.decode(b"DeadBeef").unwrap(), deadbeef);
/// assert_eq!(HEXLOWER_PERMISSIVE.encode(&deadbeef), "deadbeef");
/// ```
///
/// You can also define a shorter name:
///
/// ```rust
/// use data_encoding::{Encoding, HEXLOWER_PERMISSIVE};
/// const HEX: Encoding = HEXLOWER_PERMISSIVE;
/// ```
pub const HEXLOWER_PERMISSIVE: Encoding = Encoding::internal_new(HEXLOWER_PERMISSIVE_IMPL);
const HEXLOWER_PERMISSIVE_IMPL: &[u8] = &[
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100,
101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100,
101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97,
98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 97, 98, 99, 100, 101, 102, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 28,
];
/// Uppercase hexadecimal encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, HEXUPPER};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("0123456789ABCDEF");
/// assert_eq!(HEXUPPER, spec.encoding().unwrap());
/// ```
///
/// It is compliant with [RFC4648] and known as "base16" or "hex".
///
/// # Examples
///
/// ```rust
/// use data_encoding::HEXUPPER;
/// let deadbeef = vec![0xde, 0xad, 0xbe, 0xef];
/// assert_eq!(HEXUPPER.decode(b"DEADBEEF").unwrap(), deadbeef);
/// assert_eq!(HEXUPPER.encode(&deadbeef), "DEADBEEF");
/// ```
///
pub const HEXUPPER: Encoding = Encoding::internal_new(HEXUPPER_IMPL);
const HEXUPPER_IMPL: &[u8] = &[
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11,
12, 13, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 28,
];
/// Uppercase hexadecimal encoding with case-insensitive decoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, HEXUPPER_PERMISSIVE};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("0123456789ABCDEF");
/// spec.translate.from.push_str("abcdef");
/// spec.translate.to.push_str("ABCDEF");
/// assert_eq!(HEXUPPER_PERMISSIVE, spec.encoding().unwrap());
/// ```
///
/// # Examples
///
/// ```rust
/// use data_encoding::HEXUPPER_PERMISSIVE;
/// let deadbeef = vec![0xde, 0xad, 0xbe, 0xef];
/// assert_eq!(HEXUPPER_PERMISSIVE.decode(b"DeadBeef").unwrap(), deadbeef);
/// assert_eq!(HEXUPPER_PERMISSIVE.encode(&deadbeef), "DEADBEEF");
/// ```
pub const HEXUPPER_PERMISSIVE: Encoding = Encoding::internal_new(HEXUPPER_PERMISSIVE_IMPL);
const HEXUPPER_PERMISSIVE_IMPL: &[u8] = &[
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11,
12, 13, 14, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 28,
];
/// Padded base32 encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE32};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567");
/// spec.padding = Some('=');
/// assert_eq!(BASE32, spec.encoding().unwrap());
/// ```
///
/// It is conform to [RFC4648].
///
pub const BASE32: Encoding = Encoding::internal_new(BASE32_IMPL);
const BASE32_IMPL: &[u8] = &[
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 128, 128, 128, 128, 128, 130, 128, 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, 24,
25, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 29,
];
/// Unpadded base32 encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE32_NOPAD};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567");
/// assert_eq!(BASE32_NOPAD, spec.encoding().unwrap());
/// ```
pub const BASE32_NOPAD: Encoding = Encoding::internal_new(BASE32_NOPAD_IMPL);
const BASE32_NOPAD_IMPL: &[u8] = &[
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 50, 51, 52, 53, 54, 55, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 50, 51, 52, 53, 54, 55, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 128, 128, 128, 128, 128, 128, 128, 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, 24,
25, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 29,
];
/// Padded base32hex encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE32HEX};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("0123456789ABCDEFGHIJKLMNOPQRSTUV");
/// spec.padding = Some('=');
/// assert_eq!(BASE32HEX, spec.encoding().unwrap());
/// ```
///
/// It is conform to [RFC4648].
///
pub const BASE32HEX: Encoding = Encoding::internal_new(BASE32HEX_IMPL);
const BASE32HEX_IMPL: &[u8] = &[
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 130, 128, 128, 128, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 29,
];
/// Unpadded base32hex encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE32HEX_NOPAD};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("0123456789ABCDEFGHIJKLMNOPQRSTUV");
/// assert_eq!(BASE32HEX_NOPAD, spec.encoding().unwrap());
/// ```
pub const BASE32HEX_NOPAD: Encoding = Encoding::internal_new(BASE32HEX_NOPAD_IMPL);
const BASE32HEX_NOPAD_IMPL: &[u8] = &[
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 29,
];
/// DNSSEC base32 encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE32_DNSSEC};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("0123456789abcdefghijklmnopqrstuv");
/// spec.translate.from.push_str("ABCDEFGHIJKLMNOPQRSTUV");
/// spec.translate.to.push_str("abcdefghijklmnopqrstuv");
/// assert_eq!(BASE32_DNSSEC, spec.encoding().unwrap());
/// ```
///
/// It is conform to [RFC5155]:
///
/// - It uses a base32 extended hex alphabet.
/// - It is case-insensitive when decoding and uses lowercase when encoding.
/// - It does not use padding.
///
pub const BASE32_DNSSEC: Encoding = Encoding::internal_new(BASE32_DNSSEC_IMPL);
const BASE32_DNSSEC_IMPL: &[u8] = &[
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
116, 117, 118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
113, 114, 115, 116, 117, 118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101,
102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
110, 111, 112, 113, 114, 115, 116, 117, 118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
118, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 29,
];
/// DNSCurve base32 encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{BitOrder, Specification, BASE32_DNSCURVE};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("0123456789bcdfghjklmnpqrstuvwxyz");
/// spec.bit_order = BitOrder::LeastSignificantFirst;
/// spec.translate.from.push_str("BCDFGHJKLMNPQRSTUVWXYZ");
/// spec.translate.to.push_str("bcdfghjklmnpqrstuvwxyz");
/// assert_eq!(BASE32_DNSCURVE, spec.encoding().unwrap());
/// ```
///
/// It is conform to [DNSCurve].
///
pub const BASE32_DNSCURVE: Encoding = Encoding::internal_new(BASE32_DNSCURVE_IMPL);
const BASE32_DNSCURVE_IMPL: &[u8] = &[
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107,
108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103,
104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113,
114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99,
100, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109,
110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 128, 128, 128, 128, 128, 128, 128, 128, 10, 11,
12, 128, 13, 14, 15, 128, 16, 17, 18, 19, 20, 128, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
128, 128, 128, 128, 128, 128, 128, 10, 11, 12, 128, 13, 14, 15, 128, 16, 17, 18, 19, 20, 128,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 21,
];
/// Padded base64 encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE64};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
/// spec.padding = Some('=');
/// assert_eq!(BASE64, spec.encoding().unwrap());
/// ```
///
/// It is conform to [RFC4648].
///
pub const BASE64: Encoding = Encoding::internal_new(BASE64_IMPL);
const BASE64_IMPL: &[u8] = &[
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67, 68,
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 62, 128, 128, 128, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 130, 128,
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,
24, 25, 128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 30,
];
/// Unpadded base64 encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE64_NOPAD};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
/// assert_eq!(BASE64_NOPAD, spec.encoding().unwrap());
/// ```
pub const BASE64_NOPAD: Encoding = Encoding::internal_new(BASE64_NOPAD_IMPL);
const BASE64_NOPAD_IMPL: &[u8] = &[
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67, 68,
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 62, 128, 128, 128, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 128, 128,
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,
24, 25, 128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 30,
];
/// MIME base64 encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, Wrap, BASE64_MIME};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
/// spec.padding = Some('=');
/// spec.wrap.width = 76;
/// spec.wrap.separator.push_str("\r\n");
/// assert_eq!(BASE64_MIME, spec.encoding().unwrap());
/// ```
///
/// It is not exactly conform to [RFC2045] because it does not print the header
/// and does not ignore all characters.
///
pub const BASE64_MIME: Encoding = Encoding::internal_new(BASE64_MIME_IMPL);
const BASE64_MIME_IMPL: &[u8] = &[
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 65, 66, 67, 68,
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 129, 128, 128, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 62, 128, 128, 128, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 130, 128,
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,
24, 25, 128, 128, 128, 128, 128, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 30, 76, 13, 10,
];
/// Padded base64url encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE64URL};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
/// spec.padding = Some('=');
/// assert_eq!(BASE64URL, spec.encoding().unwrap());
/// ```
///
/// It is conform to [RFC4648].
///
pub const BASE64URL: Encoding = Encoding::internal_new(BASE64URL_IMPL);
const BASE64URL_IMPL: &[u8] = &[
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66, 67, 68,
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 62, 128, 128, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 130, 128,
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,
24, 25, 128, 128, 128, 128, 63, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61, 30,
];
/// Unpadded base64url encoding
///
/// This encoding is a static version of:
///
/// ```rust
/// # use data_encoding::{Specification, BASE64URL_NOPAD};
/// let mut spec = Specification::new();
/// spec.symbols.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
/// assert_eq!(BASE64URL_NOPAD, spec.encoding().unwrap());
/// ```
pub const BASE64URL_NOPAD: Encoding = Encoding::internal_new(BASE64URL_NOPAD_IMPL);
const BASE64URL_NOPAD_IMPL: &[u8] = &[
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 65, 66, 67, 68,
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 62, 128, 128, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 128, 128,
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,
24, 25, 128, 128, 128, 128, 63, 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 30,
];