data-encoding-2.1.2/Cargo.toml.orig010064000017500001750000000014631341172433600153250ustar0000000000000000[package] name = "data-encoding" version = "2.1.2" authors = ["Julien Cretin "] license = "MIT" edition = "2018" keywords = ["base-conversion", "encoding", "base64", "base32", "hex"] categories = ["encoding"] readme = "README.md" repository = "https://github.com/ia0/data-encoding" documentation = "https://docs.rs/data-encoding" description = "Efficient and customizable data-encoding functions" include = ["Cargo.toml", "LICENSE", "README.md", "src/lib.rs"] [badges] appveyor = { repository = "ia0/data-encoding" } coveralls = { repository = "ia0/data-encoding" } is-it-maintained-issue-resolution = { repository = "ia0/data-encoding" } is-it-maintained-open-issues = { repository = "ia0/data-encoding" } maintenance = { status = "passively-maintained" } travis-ci = { repository = "ia0/data-encoding" } data-encoding-2.1.2/Cargo.toml0000644000000025140000000000000115720ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "data-encoding" version = "2.1.2" authors = ["Julien Cretin "] include = ["Cargo.toml", "LICENSE", "README.md", "src/lib.rs"] description = "Efficient and customizable data-encoding functions" documentation = "https://docs.rs/data-encoding" readme = "README.md" keywords = ["base-conversion", "encoding", "base64", "base32", "hex"] categories = ["encoding"] license = "MIT" repository = "https://github.com/ia0/data-encoding" [badges.appveyor] repository = "ia0/data-encoding" [badges.coveralls] repository = "ia0/data-encoding" [badges.is-it-maintained-issue-resolution] repository = "ia0/data-encoding" [badges.is-it-maintained-open-issues] repository = "ia0/data-encoding" [badges.maintenance] status = "passively-maintained" [badges.travis-ci] repository = "ia0/data-encoding" data-encoding-2.1.2/LICENSE010064000017500001750000000021341334745751600134520ustar0000000000000000The MIT License (MIT) Copyright (c) 2015-2017 Julien Cretin Copyright (c) 2017 Google Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. data-encoding-2.1.2/README.md010064000017500001750000000065301334745751600137300ustar0000000000000000## Common use-cases This library provides the following common encodings: - `HEXLOWER`: lowercase hexadecimal - `HEXLOWER_PERMISSIVE`: lowercase hexadecimal with case-insensitive decoding - `HEXUPPER`: uppercase hexadecimal - `HEXUPPER_PERMISSIVE`: uppercase hexadecimal with case-insensitive decoding - `BASE32`: RFC4648 base32 - `BASE32_NOPAD`: RFC4648 base32 without padding - `BASE32_DNSSEC`: RFC5155 base32 - `BASE32_DNSCURVE`: DNSCurve base32 - `BASE32HEX`: RFC4648 base32hex - `BASE32HEX_NOPAD`: RFC4648 base32hex without padding - `BASE64`: RFC4648 base64 - `BASE64_NOPAD`: RFC4648 base64 without padding - `BASE64_MIME`: RFC2045-like base64 - `BASE64URL`: RFC4648 base64url - `BASE64URL_NOPAD`: RFC4648 base64url without padding Typical usage looks like: ```rust // allocating functions BASE64.encode(&input_to_encode) HEXLOWER.decode(&input_to_decode) // in-place functions BASE32.encode_mut(&input_to_encode, &mut encoded_output) BASE64_URL.decode_mut(&input_to_decode, &mut decoded_output) ``` See the [documentation] or the [changelog] for more details. ## Custom use-cases This library also provides the possibility to define custom little-endian ASCII base-conversion encodings for bases of size 2, 4, 8, 16, 32, and 64 (for which all above use-cases are particular instances). It supports: - padded and unpadded encodings - 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 The typical definition of a custom encoding looks like: ```rust lazy_static! { static ref HEX: Encoding = { let mut spec = Specification::new(); spec.symbols.push_str("0123456789abcdef"); spec.translate.from.push_str("ABCDEF"); spec.translate.to.push_str("abcdef"); spec.encoding().unwrap() }; static ref BASE64: Encoding = { let mut spec = Specification::new(); spec.symbols.push_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); spec.padding = Some('='); spec.encoding().unwrap() }; } ``` You may also use the [macro] library to define a compile-time custom encoding: ```rust const HEX: Encoding = new_encoding!{ symbols: "0123456789abcdef", translate_from: "ABCDEF", translate_to: "abcdef", }; const BASE64: Encoding = new_encoding!{ symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", padding: '=', }; ``` See the [documentation] or the [changelog] for more details. ## Performance The performance of the encoding and decoding functions (for both common and custom encodings) are similar to existing implementations in C, Rust, and other high-performance languages (see how to run the benchmarks on [github]). ## Swiss-knife binary This crate is a library. If you are looking for the [binary] using this library, see the installation instructions on [github]. [binary]: https://crates.io/crates/data-encoding-bin [changelog]: https://github.com/ia0/data-encoding/blob/master/lib/CHANGELOG.md [documentation]: https://docs.rs/data-encoding [github]: https://github.com/ia0/data-encoding [macro]: https://crates.io/crates/data-encoding-macro data-encoding-2.1.2/src/lib.rs010064000017500001750000003150351341171735100143430ustar0000000000000000//! Efficient and customizable data-encoding functions //! //! This [crate] provides little-endian ASCII base-conversion encodings for //! bases of size 2, 4, 8, 16, 32, and 64. It supports: //! //! - padded and unpadded encodings //! - 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 //! //! The performance of the encoding and decoding functions are similar to //! existing implementations (see how to run the benchmarks on [github]). //! //! This is the library documentation. If you are looking for the [binary], see //! the installation instructions on [github]. //! //! # 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"); //! ``` //! //! If you use the [`lazy_static`] crate, you can define a global encoding: //! //! ```rust,ignore //! lazy_static! { //! static ref HEX: Encoding = { //! let mut spec = Specification::new(); //! spec.symbols.push_str("0123456789abcdef"); //! spec.translate.from.push_str("ABCDEF"); //! spec.translate.to.push_str("abcdef"); //! spec.encoding().unwrap() //! }; //! } //! ``` //! //! You may also use the [macro] library to define a compile-time custom encoding: //! //! ```rust,ignore //! const HEX: Encoding = new_encoding!{ //! symbols: "0123456789abcdef", //! translate_from: "ABCDEF", //! translate_to: "abcdef", //! }; //! const BASE64: Encoding = new_encoding!{ //! symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", //! padding: '=', //! }; //! ``` //! //! # Properties //! //! The [base16], [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 common base64 implementations //! (like the `rustc-serialize` crate, the `base64` crate, or the `base64` GNU //! program). 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 `rustc-serialize` crate, the `base64` crate, and the `base64` GNU //! program: //! //! | Input | `data-encoding` | `rustc` | `base64` | GNU `base64` | //! | ---------- | --------------- | -------- | -------- | ------------- | //! | `AAB=` | `Trailing(2)` | `[0, 0]` | `[0, 0]` | `\x00\x00` | //! | `AA\nB=` | `Length(4)` | `[0, 0]` | `Length` | `\x00\x00` | //! | `AAB` | `Length(0)` | `[0, 0]` | `[0, 0]` | Invalid input | //! | `A\rA\nB=` | `Length(4)` | `[0, 0]` | `Err(1)` | Invalid input | //! | `-_\r\n` | `Symbol(0)` | `[251]` | `Err(0)` | Invalid input | //! | `AA==AA==` | `[0, 0]` | `Err` | `Err(2)` | `\x00\x00` | //! //! We can summarize these discrepancies as follows: //! //! | Discrepancy | `data-encoding` | `rustc` | `base64` | GNU `base64` | //! | ----------- | --------------- | ------- | -------- | ------------ | //! | Check trailing bits | Yes | No | No | No | //! | Ignored characters | None | `\r` and `\n` | None | `\n` | //! | Translated characters | None | `-_` mapped to `+/` | None | None | //! | Check padding | Yes | No | No | Yes | //! | Support concatenated input | Yes | No | 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. //! //! # Migration //! //! The [changelog] describes the changes between v1 and v2. Here are the //! migration steps for common usage: //! //! | v1 | v2 | //! | --------------------------- | --------------------------- | //! | `use data_encoding::baseNN` | `use data_encoding::BASENN` | //! | `baseNN::function` | `BASENN.method` | //! | `baseNN::function_nopad` | `BASENN_NOPAD.method` | //! //! [`Encoding`]: struct.Encoding.html //! [`Specification`]: struct.Specification.html //! [`is_canonical`]: struct.Encoding.html#method.is_canonical //! [`lazy_static`]: https://crates.io/crates/lazy_static //! [RFC4648]: https://tools.ietf.org/html/rfc4648 //! [base16]: constant.HEXUPPER.html //! [base32]: constant.BASE32.html //! [base32hex]: constant.BASE32HEX.html //! [base64]: constant.BASE64.html //! [base64url]: constant.BASE64URL.html //! [binary]: https://crates.io/crates/data-encoding-bin //! [canonical]: https://tools.ietf.org/html/rfc4648#section-3.5 //! [changelog]: //! https://github.com/ia0/data-encoding/blob/master/lib/CHANGELOG.md //! [constants]: index.html#constants //! [crate]: https://crates.io/crates/data-encoding //! [github]: https://github.com/ia0/data-encoding //! [macro]: https://crates.io/crates/data-encoding-macro #![warn(unused_results, missing_docs)] macro_rules! check { ($e: expr, $c: expr) => { if !$c { return Err($e); } }; } trait Static: 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 Static> for On { fn val(self) -> Option { None } } #[derive(Copy, Clone)] struct Os(T); impl Static> for Os { fn val(self) -> Option { Some(self.0) } } macro_rules! dispatch { (let $var: ident: bool = $val: expr; $($body: tt)*) => { match $val { false => { let $var = Bf; dispatch!($($body)*) }, true => { let $var = Bt; 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().offset((n * i) as isize); std::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().offset((n * i) as isize); std::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(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, } /// 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, } impl std::error::Error for DecodeError { fn description(&self) -> &str { match self.kind { DecodeKind::Length => "invalid length", DecodeKind::Symbol => "invalid symbol", DecodeKind::Trailing => "non-zero trailing bits", DecodeKind::Padding => "invalid padding length", } } } impl std::fmt::Display for DecodeError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { use std::error::Error; write!(f, "{} at {}", self.description(), 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 { debug_assert!(1 <= bit && bit <= 6); match bit { 1 | 2 | 4 => 1, 3 | 6 => 3, 5 => 5, _ => unreachable!(), } } fn dec(bit: usize) -> usize { enc(bit) * 8 / bit } fn encode_len>(bit: B, len: usize) -> usize { div_ceil(8 * len, bit.val()) } fn encode_block, M: Static>( 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 in 0 .. input.len() { x |= (input[i] as u64) << 8 * order(msb, enc(bit), i); } for i in 0 .. output.len() { let y = x >> bit * order(msb, dec(bit), i); output[i] = symbols[y as usize % 256]; } } fn encode_mut, M: Static>( 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, M: Static>( 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 |= (y as u64) << bit * order(msb, dec(bit), j); } for j in 0 .. output.len() { output[j] = (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, M: Static>( 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, M: Static>( 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>(bit: B, values: &[u8; 256], input: &[u8]) -> Result { 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>(bit: B, len: usize) -> usize { encode_len(bit, len) } fn encode_base, M: Static>( 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, P: Static>>(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, M: Static, P: Static>>( 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 i in olen .. output.len() { output[i] = pad; } } fn encode_wrap_len< 'a, B: Static, P: Static>, W: Static>, >( 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, M: Static, P: Static>, W: Static>, >( 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, P: Static>( 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, P: Static>( bit: B, pad: P, len: usize, ) -> Result { 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>(bit: B, len: usize) -> Result { 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, M: Static>( bit: B, msb: M, ctb: bool, values: &[u8; 256], input: &[u8], output: &mut [u8], ) -> Result { 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, M: Static, P: Static>( bit: B, msb: M, ctb: bool, values: &[u8; 256], pad: P, input: &[u8], output: &mut [u8], ) -> Result { 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, M: Static, P: Static>( 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. fn decode_wrap_mut, M: Static, P: Static, I: Static>( bit: B, msb: M, ctb: bool, values: &[u8; 256], pad: P, has_ignore: I, input: &[u8], output: &mut [u8], ) -> Result { 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"); /// ``` #[derive(Debug, Copy, Clone, PartialEq, Eq)] 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. /// /// [RFC4648]: https://tools.ietf.org/html/rfc4648 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, } use crate::BitOrder::*; #[doc(hidden)] pub type InternalEncoding = std::borrow::Cow<'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. #[derive(Debug, Clone)] 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. #[derive(Debug, Clone)] 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, 2N) (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, 2N), 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, /// 2N). 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 /// /// 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 (which is not a symbol) 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")); /// ``` /// /// [base-conversion]: /// https://en.wikipedia.org/wiki/Positional_notation#Base_conversion /// [canonical]: https://tools.ietf.org/html/rfc4648#section-3.5 #[derive(Debug, Clone)] 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, /// 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, } 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() }, } } } 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 { 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 = 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 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 = self.pad(); let wrap: Option<(usize, &[u8])> = self.wrap(); encode_wrap_mut(bit, msb, self.sym(), pad, wrap, input, output) } } /// Returns encoded `input` /// /// # Examples /// /// ```rust /// use data_encoding::BASE64; /// assert_eq!(BASE64.encode(b"Hello world"), "SGVsbG8gd29ybGQ="); /// ``` 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 { 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 pub fn decode_mut(&self, input: &[u8], output: &mut [u8]) -> Result { 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"); /// ``` /// /// [`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 pub fn decode(&self, input: &[u8]) -> Result, 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 pub fn specification(&self) -> Specification { let mut specification = Specification::new(); specification .symbols .push_str(std::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 = std::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 fn internal_new(implementation: &'static [u8]) -> Encoding { Encoding(std::borrow::Cow::Borrowed(implementation)) } #[doc(hidden)] pub fn internal_implementation(&self) -> &[u8] { &self.0 } } #[derive(Debug, Copy, Clone)] enum SpecificationErrorImpl { BadSize, NotAscii, Duplicate(u8), ExtraPadding, WrapLength, WrapWidth(u8), FromTo, Undefined(u8), } use crate::SpecificationErrorImpl::*; /// Specification error #[derive(Debug, Copy, Clone)] pub struct SpecificationError(SpecificationErrorImpl); impl std::fmt::Display for SpecificationError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::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), } } } 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", } } } impl Specification { /// Returns the specified encoding /// /// # Errors /// /// Returns an error if the specification is invalid. pub fn encoding(&self) -> Result { 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); Ok(v[i as usize] = x) }; for v in 0 .. symbols.len() { set(&mut values, symbols[v], 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(std::borrow::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 = HEXLOWER_IMPL; const HEXLOWER_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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 = HEXLOWER_PERMISSIVE_IMPL; const HEXLOWER_PERMISSIVE_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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"); /// ``` /// /// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-8 pub const HEXUPPER: Encoding = HEXUPPER_IMPL; const HEXUPPER_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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 = HEXUPPER_PERMISSIVE_IMPL; const HEXUPPER_PERMISSIVE_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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]. /// /// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-6 pub const BASE32: Encoding = BASE32_IMPL; const BASE32_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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 = BASE32_NOPAD_IMPL; const BASE32_NOPAD_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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]. /// /// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-7 pub const BASE32HEX: Encoding = BASE32HEX_IMPL; const BASE32HEX_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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 = BASE32HEX_NOPAD_IMPL; const BASE32HEX_NOPAD_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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. /// /// [RFC5155]: https://tools.ietf.org/html/rfc5155 pub const BASE32_DNSSEC: Encoding = BASE32_DNSSEC_IMPL; const BASE32_DNSSEC_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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]. /// /// [DNSCurve]: https://dnscurve.org/in-implement.html pub const BASE32_DNSCURVE: Encoding = BASE32_DNSCURVE_IMPL; const BASE32_DNSCURVE_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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]. /// /// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-4 pub const BASE64: Encoding = BASE64_IMPL; const BASE64_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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 = BASE64_NOPAD_IMPL; const BASE64_NOPAD_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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. /// /// [RFC2045]: https://tools.ietf.org/html/rfc2045 pub const BASE64_MIME: Encoding = BASE64_MIME_IMPL; const BASE64_MIME_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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]. /// /// [RFC4648]: https://tools.ietf.org/html/rfc4648#section-5 pub const BASE64URL: Encoding = BASE64URL_IMPL; const BASE64URL_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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 = BASE64URL_NOPAD_IMPL; const BASE64URL_NOPAD_IMPL: Encoding = Encoding(std::borrow::Cow::Borrowed(&[ 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, ])); data-encoding-2.1.2/.cargo_vcs_info.json0000644000000001120000000000000135640ustar00{ "git": { "sha1": "ab1ca734ca8d9b25560c925439cf78343566c79e" } }