Coverage Report

Created: 2025-12-31 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/base64ct-1.8.1/src/alphabet/shacrypt.rs
Line
Count
Source
1
//! `crypt(3)` Base64 encoding for sha* family.
2
3
use super::{Alphabet, DecodeStep, EncodeStep};
4
5
/// Little endian variant of the `crypt(3)` Base64 encoding.
6
///
7
/// Used by the following schemes:
8
/// - md5_crypt
9
/// - scrypt
10
/// - sha1_crypt
11
/// - sha256_crypt
12
/// - sha512_crypt
13
/// - yescrypt
14
///
15
/// ```text
16
/// [.-9]      [A-Z]      [a-z]
17
/// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a
18
/// ```
19
///
20
/// This uses the same alphabet as [`Base64Crypt`][`crate::Base64Crypt`], but uses a little endian
21
/// variant of Base64.
22
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
23
pub struct Base64ShaCrypt;
24
25
impl Alphabet for Base64ShaCrypt {
26
    const BASE: u8 = b'.';
27
28
    const DECODER: &'static [DecodeStep] = &[
29
        DecodeStep::Range(b'.'..=b'9', -45),
30
        DecodeStep::Range(b'A'..=b'Z', -52),
31
        DecodeStep::Range(b'a'..=b'z', -58),
32
    ];
33
34
    const ENCODER: &'static [EncodeStep] =
35
        &[EncodeStep::Apply(b'9', 7), EncodeStep::Apply(b'Z', 6)];
36
37
    const PADDED: bool = false;
38
39
    type Unpadded = Self;
40
41
    #[inline(always)]
42
0
    fn decode_3bytes(src: &[u8], dst: &mut [u8]) -> i16 {
43
0
        debug_assert_eq!(src.len(), 4);
44
0
        debug_assert!(dst.len() >= 3, "dst too short: {}", dst.len());
45
46
0
        let c0 = Self::decode_6bits(src[0]);
47
0
        let c1 = Self::decode_6bits(src[1]);
48
0
        let c2 = Self::decode_6bits(src[2]);
49
0
        let c3 = Self::decode_6bits(src[3]);
50
51
0
        dst[0] = (c0 | ((c1 & 0x3) << 6)) as u8;
52
0
        dst[1] = ((c1 >> 2) | ((c2 & 0xF) << 4)) as u8;
53
0
        dst[2] = ((c2 >> 4) | (c3 << 2)) as u8;
54
55
0
        ((c0 | c1 | c2 | c3) >> 8) & 1
56
0
    }
57
58
    #[inline(always)]
59
0
    fn encode_3bytes(src: &[u8], dst: &mut [u8]) {
60
0
        debug_assert_eq!(src.len(), 3);
61
0
        debug_assert!(dst.len() >= 4, "dst too short: {}", dst.len());
62
63
0
        let b0 = src[0] as i16;
64
0
        let b1 = src[1] as i16;
65
0
        let b2 = src[2] as i16;
66
67
0
        dst[0] = Self::encode_6bits(b0 & 63);
68
0
        dst[1] = Self::encode_6bits(((b1 << 2) | (b0 >> 6)) & 63);
69
0
        dst[2] = Self::encode_6bits(((b2 << 4) | (b1 >> 4)) & 63);
70
0
        dst[3] = Self::encode_6bits(b2 >> 2);
71
0
    }
72
}