/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 | | } |