[Freeipa-devel] [freeipa PR#317][comment] Unify password generation across FreeIPA

tiran freeipa-github-notification at redhat.com
Thu Dec 8 17:37:27 UTC 2016


  URL: https://github.com/freeipa/freeipa/pull/317
Title: #317: Unify password generation across FreeIPA

tiran commented:
"""
```
#!/usr/bin/python3
import math
import random
import string


class TokenGenerator(object):
    """Simple, tunable token generator

    TokenGenerator(uppercase=3, lowercase=3, digits=0, special=None)

    At least 3 upper and 3 lower case ASCII chars, may contain digits, no
    special chars.

    128 bits entropy: secure
    256 bits of entropy: secure enough if you care about quantum computers
    """
    uppercase = frozenset(string.ascii_uppercase)
    lowercase = frozenset(string.ascii_lowercase)
    digits = frozenset(string.digits)
    # without: = # ' " \ `
    special = frozenset('!$%&()*+,-./:;<>?@[]^_{|}~')

    def __init__(self, uppercase=1, lowercase=1, digits=1, special=1):
        self.rng = random.SystemRandom()
        self.requirements = dict(
            uppercase=uppercase,
            lowercase=lowercase,
            digits=digits,
            special=special
        )
        chars = set()
        for symclass, req in self.requirements.items():
            if req is not None:
                chars.update(getattr(self, symclass))
        self.chars = tuple(chars)

    def __call__(self, entropy_bits=128):
        length = int(math.ceil(entropy_bits / math.log(len(self.chars), 2)))
        while True:
            token = ''.join(self.rng.choice(self.chars) for _ in range(length))
            tokenset = set(token)
            token_ok = True
            for symclass, req in self.requirements.items():
                if req is None or req <= 0:
                    continue
                reqchars = getattr(self, symclass)
                if len(tokenset.intersection(reqchars)) < req:
                    token_ok = False
                    break
            if token_ok:
                return token


if __name__ == '__main__':
    pwgen = TokenGenerator(special=None)
    for i in range(100):
        print(pwgen())
```
"""

See the full comment at https://github.com/freeipa/freeipa/pull/317#issuecomment-265803218


More information about the Freeipa-devel mailing list