Skip to content
Snippets Groups Projects
diceware.py 1.91 KiB
Newer Older
  • Learn to ignore specific revisions
  • ulif's avatar
    ulif committed
    import argparse
    
    ulif's avatar
    ulif committed
    import os
    
    ulif's avatar
    ulif committed
    import re
    
    ulif's avatar
    ulif committed
    import sys
    
    from random import SystemRandom
    
    
    ulif's avatar
    ulif committed
    
    #: The directory in which wordlists are stored
    SRC_DIR = os.path.dirname(__file__)
    
    
    ulif's avatar
    ulif committed
    #: A regular expression matching ASCII chars
    RE_ASCII_CHARS = re.compile('^[a-zA-Z]{2}$')
    
    
    #: Special chars inserted on demand
    SPECIAL_CHARS = "~!#$%^&*()-=+[]\{}:;\"'<>?/0123456789"
    
    ulif's avatar
    ulif committed
    
    
    ulif's avatar
    ulif committed
    
    
    ulif's avatar
    ulif committed
    def handle_options(args):
        """Handle commandline options.
        """
        parser = argparse.ArgumentParser(description="Create a passphrase")
        args = parser.parse_args(args)
        return args
    
    
    
    ulif's avatar
    ulif committed
    def get_wordlist(path):
        """Parse file at `path` and build a word list of it.
    
    ulif's avatar
    ulif committed
    
        A wordlist is expected to contain lines of format::
    
            <NUMS><TAB><WORD>\n
    
        for instance::
    
            136512\tTerm
    
    
    ulif's avatar
    ulif committed
        """
        result = []
        with open(path, 'r') as fd:
    
    ulif's avatar
    ulif committed
            result = [line.strip() for line in fd.readlines()
                      if line.strip() != '']
    
    ulif's avatar
    ulif committed
        return result
    
    
    ulif's avatar
    ulif committed
    def get_wordlist_path(lang):
        """Get path to a wordlist file for language `lang`.
    
        The `lang` string is a 2-char country code. Invalid codes raise a
        ValueError.
        """
        if not RE_ASCII_CHARS.match(lang):
            raise ValueError("Not a valid language code: %s" % lang)
    
    ulif's avatar
    ulif committed
        basename = 'wordlist_%s.txt' % lang
    
    ulif's avatar
    ulif committed
        return os.path.abspath(os.path.join(SRC_DIR, basename.lower()))
    
    
    
    def get_passphrase(wordnum=6, specials=True, separator='', lang='en',
                       capitalized=True):
        """Get a diceware passphrase.
        """
        word_list = get_wordlist(get_wordlist_path(lang))
        rnd = SystemRandom()
        words = [rnd.choice(word_list) for x in range(wordnum)]
        if capitalized:
            words = [x.capitalize() for x in words]
        result = separator.join(words)
        result = list(result)
        result[rnd.choice(range(len(result)))] = rnd.choice(SPECIAL_CHARS)
        result = ''.join(result)
        return result
    
    
    
    ulif's avatar
    ulif committed
    def main(args=1):
        if args is 1:
            args = sys.argv[1:]
        options = handle_options(args)