Struct data_encoding::NoPad
[−]
[src]
pub struct NoPad { /* fields omitted */ }
Base-conversion encoding (without padding)
Theory
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: most or least significant bit first
- The symbols function S from [0, 2N) (called values and written
uN
) to symbols (represented asu8
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
touN
- 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 (i.e. different inputs decode to different outputs), 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:
[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)
Practice
use data_encoding::Builder; let binary = Builder::new(b"01").no_pad().unwrap(); let octal = Builder::new(b"01234567").no_pad().unwrap(); let hexadecimal = Builder::new(b"0123456789abcdef").no_pad().unwrap(); 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):
[ 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:
use data_encoding::{BASE64, Builder}; let octal = Builder::new(b"01234567").no_pad().unwrap(); assert_eq!(BASE64.no_pad().encode(b"B"), "Qg"); assert_eq!(octal.encode(b"B"), "204");
We have the following diagram, where the base64 values are written between parentheses:
[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
Methods
impl NoPad
[src]
fn encode_len(&self, len: usize) -> usize
Returns the encoded length of an input of length len
See encode_mut
for when to use it.
fn encode_mut(&self, input: &[u8], output: &mut [u8])
Encodes input
in output
Panics
Panics if output
's length does not match the result of encode_len
for input
's length.
Examples
let output = &mut buffer[0 .. base64.encode_len(input.len())]; base64.encode_mut(input, output);
fn encode(&self, input: &[u8]) -> String
Returns encoded input
Examples
use data_encoding::BASE64; assert_eq!(BASE64.no_pad().encode(b"Hello world"), "SGVsbG8gd29ybGQ");
fn decode_len(&self, len: usize) -> Result<usize, DecodeError>
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 error position is the greatest valid length smaller than len
.
fn decode_mut(&self, input: &[u8], output: &mut [u8]) -> Result<(), DecodeError>
Decodes input
in output
Panics
Panics if output
's length does not match the result of decode_len
for input
's length. Also panics if decode_len
fails for input
's
length.
Errors
Returns an error if input
is invalid. The error kind can be Symbol
or Trailing
.
Examples
let output = &mut buffer[0 .. base64.decode_len(input.len()).unwrap()]; base64.decode_mut(input, output).unwrap();
fn decode(&self, input: &[u8]) -> Result<Vec<u8>, DecodeError>
Returns decoded input
Errors
Returns an error if input
is invalid. The error kind can be
Length
, Symbol
, or Trailing
.
Examples
use data_encoding::BASE64; assert_eq!(BASE64.no_pad().decode(b"SGVsbG8gd29ybGQ").unwrap(), b"Hello world");
fn bit_width(&self) -> usize
Returns the bit-width
fn bit_order(&self) -> BitOrder
Returns the bit-order
fn symbols(&self) -> &str
Returns the symbols
fn translate(&self) -> (String, String)
Returns the non-canonical symbols
Non-canonical symbols are ASCII characters i for which V(i) is defined but S(V(i)) is different from i. In other words, these characters cannot be produced by the encoding function but are still recognized by the decoding function and behave as the canonical symbol of the same value.
The result (from, to)
has the following properties:
from
andto
are ASCII and have the same length- All non-canonical symbols are listed in
from
in ascending order from[i]
is a non-canonical symbol that behaves asto[i]
for all i
Examples
let (from, to) = data_encoding::HEXLOWER_PERMISSIVE.translate(); assert_eq!((from.as_str(), to.as_str()), ("ABCDEF", "abcdef"));
fn check_trailing_bits(&self) -> Option<bool>
Whether trailing bits are checked
Returns None
for bases that don't need to check trailing bits (like
base2, base4, and base16). Otherwise, for bases that would need it (like
base8, base32, and base64), returns whether trailing bits are checked.
Trait Implementations
impl Debug for NoPad
[src]
impl Copy for NoPad
[src]
impl Clone for NoPad
[src]
fn clone(&self) -> NoPad
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0
Performs copy-assignment from source
. Read more
impl PartialEq for NoPad
[src]
fn eq(&self, __arg_0: &NoPad) -> bool
This method tests for self
and other
values to be equal, and is used by ==
. Read more
fn ne(&self, __arg_0: &NoPad) -> bool
This method tests for !=
.