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
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
52
53
54
//! ANSI X.923 for Rust.
//!
//! [Wikipedia Section](https://en.wikipedia.org/wiki/Padding_(cryptography)#ANSI_X.923)

use std::iter;

/// Pad some bytes with ANSI X.923, modifying the input.
///
/// # Example
///
/// ```rust
/// use x_923::pad_buffer;
///
/// let mut buffer: Vec<u8> = vec![255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255];
///
/// pad_buffer(&mut buffer, 8);
///
/// assert_eq!(buffer.as_slice(), &[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 4]);
/// ```
pub fn pad_buffer(mut buffer: &mut Vec<u8>, block_size: u8) {
    let pad_len = buffer.len() % (usize::from(block_size));

    buffer.reserve_exact(pad_len);

    buffer.extend(iter::repeat(0).take(pad_len - 1));

    buffer.push(pad_len as u8);
}

/// Un-pad some bytes with ANSI X.923, modifying the input.
pub fn un_pad_buffer(mut buffer: &mut Vec<u8>) {
    if let Some(&pad_len) = buffer.last() {
        let len = buffer.len();
        buffer.truncate(len - pad_len as usize);
    }
}

/// Pad some bytes with ANSI X.923, cloning the input.
pub fn pad(input: &[u8], block_size: u8) -> Vec<u8> {
    let mut buffer = input.to_owned();

    pad_buffer(&mut buffer, block_size);

    buffer
}

/// Un-pad some bytes with ANSI X.923, cloning the input.
pub fn un_pad(input: &[u8]) -> Vec<u8> {
    let mut buffer = input.to_owned();

    un_pad_buffer(&mut buffer);

    buffer
}