Home

rs-spectre @main - refs - log -
-
https://git.jolheiser.com/rs-spectre.git
Rust implementation for Spectre/Masterpassword
rs-spectre / spectre / src / template.rs
- raw
  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
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
/// The template to use for secret generation, patterns are described in [`templates`]
#[derive(Debug)]
pub enum Template {
    Maximum,
    Long,
    Medium,
    Short,
    Pin,
    Name,
    Phrase,
    Basic,
}

/// Any error from parsing a Template from a string
#[derive(Debug)]
pub enum ParseTemplateError {
    Invalid,
}

impl std::str::FromStr for Template {
    type Err = ParseTemplateError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.to_uppercase().as_str() {
            "MAXIMUM" => Ok(Self::Maximum),
            "LONG" => Ok(Self::Long),
            "MEDIUM" => Ok(Self::Medium),
            "SHORT" => Ok(Self::Short),
            "PIN" => Ok(Self::Pin),
            "NAME" => Ok(Self::Name),
            "PHRASE" => Ok(Self::Phrase),
            "BASIC" => Ok(Self::Basic),
            _ => Err(ParseTemplateError::Invalid),
        }
    }
}

/// The list of templates for Spectre generation, the mapping for each char is found in [`chars`]
pub(crate) fn templates<'s>(t: Template) -> Vec<&'s str> {
    match t {
        Template::Maximum => vec![
            "anoxxxxxxxxxxxxxxxxx",
            "axxxxxxxxxxxxxxxxxno",
        ],
        Template::Long => vec![
            "CvcvnoCvcvCvcv",
            "CvcvCvcvnoCvcv",
            "CvcvCvcvCvcvno",
            "CvccnoCvcvCvcv",
            "CvccCvcvnoCvcv",
            "CvccCvcvCvcvno",
            "CvcvnoCvccCvcv",
            "CvcvCvccnoCvcv",
            "CvcvCvccCvcvno",
            "CvcvnoCvcvCvcc",
            "CvcvCvcvnoCvcc",
            "CvcvCvcvCvccno",
            "CvccnoCvccCvcv",
            "CvccCvccnoCvcv",
            "CvccCvccCvcvno",
            "CvcvnoCvccCvcc",
            "CvcvCvccnoCvcc",
            "CvcvCvccCvccno",
            "CvccnoCvcvCvcc",
            "CvccCvcvnoCvcc",
            "CvccCvcvCvccno",
        ],
        Template::Medium => vec!["CvcnoCvc", "CvcCvcno"],
        Template::Short => vec!["Cvcn"],
        Template::Pin => vec!["nnnn"],
        Template::Name => vec!["cvccvcvcv"],
        Template::Phrase => vec![
            "cvcc cvc cvccvcv cvc",
            "cvc cvccvcvcv cvcv",
            "cv cvccv cvc cvcvccv",
        ],
        Template::Basic => vec![
            "aaanaaan",
            "aannaaan",
            "aaannaaa",
        ],
    }
}

/// A mapping of each template char to a set of possible characters
pub(crate) fn chars(u: &u8) -> &str {
    match *u as char {
        'V' => "AEIOU",
        'C' => "BCDFGHJKLMNPQRSTVWXYZ",
        'v' => "aeiou",
        'c' => "bcdfghjklmnpqrstvwxyz",
        'A' => "AEIOUBCDFGHJKLMNPQRSTVWXYZ",
        'a' => "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz",
        'n' => "0123456789",
        'o' => "@&%?,=[]_:-+*$#!'^~;()/.",
        'x' => "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
        ' ' => " ",
        _ => panic!("unexpected character"),
    }
}