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 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 (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]

Returns the encoded length of an input of length len

See encode_mut for when to use it.

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);

Returns encoded input

Examples

use data_encoding::BASE64;
assert_eq!(BASE64.no_pad().encode(b"Hello world"), "SGVsbG8gd29ybGQ");

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.

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();

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");

Returns the bit-width

Returns the bit-order

Returns the symbols

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 and to 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 as to[i] for all i

Examples

let (from, to) = data_encoding::HEXLOWER_PERMISSIVE.translate();
assert_eq!((from.as_str(), to.as_str()), ("ABCDEF", "abcdef"));

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]

Formats the value using the given formatter.

impl Copy for NoPad
[src]

impl Clone for NoPad
[src]

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

impl PartialEq for NoPad
[src]

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

impl Eq for NoPad
[src]