Skip to main content
Became Hot Network Question
added 2 characters in body
Source Link
toolic
  • 15.9k
  • 6
  • 29
  • 217
#####################################################

# Name: pwgen
# Author: Muhammad Altaaf <[email protected]>
# Description: A random password generator in your
# toolset.

#####################################################

from __future__ import annotations

import secrets
import string
import sys
import typing
from argparse import ArgumentParser, RawDescriptionHelpFormatter
from dataclasses import dataclass

if typing.TYPE_CHECKING:
    from argparse import Namespace

PROG_NAME = "pwgen"
PROG_DESC = """
██████╗ ██╗    ██╗ ██████╗ ███████╗███╗   ██╗
██╔══██╗██║    ██║██╔════╝ ██╔════╝████╗  ██║
██████╔╝██║ █╗ ██║██║  ███╗█████╗  ██╔██╗ ██║
██╔═══╝ ██║███╗██║██║   ██║██╔══╝  ██║╚██╗██║
██║     ╚███╔███╔╝╚██████╔╝███████╗██║ ╚████║
╚═╝      ╚══╝╚══╝  ╚═════╝ ╚══════╝╚═╝  ╚═══╝

A random password generator in your toolset.
"""

PROG_VERSION = "1.1.0"
PROG_AUTHOR = "Muhammad Altaaf"
PROG_AUTHOR_CONTACT = "[email protected]"
PROG_EPILOG = f"""\
Version {PROG_VERSION}.
Written by {PROG_AUTHOR} <{PROG_AUTHOR_CONTACT}>.
"""


@dataclass(frozen=True)
class _Config:
    letters: bool = True
    digits: bool = True
    punct: bool = True
    length: int = 8

    def __post_init__(self):
        if not (self.letters or self.digits or self.punct):
            print(
                "At least one of the three components (alphabets, numbers or \
                symbols) must be allowed",
                file=sys.stderr,
            )
            sys.exit(1)


def _gen_passwd(config: _Config) -> str:
    """The main password generator."""

    passwd_len = config.length
    # string to get password characters from
    base = ""
    # the password
    passwd = ""

    if config.letters:
        base += string.ascii_letters
    if config.digits:
        base += string.digits
    if config.punct:
        base += string.punctuation

    for _ in range(passwd_len):
        while (char := secrets.choice(base)) == "\\":
            continue
        passwd += char

    return passwd


def parse_opts() -> Namespace:
    """Parse command line options and return Namespace object."""

    o_parser = ArgumentParser(
        prog=PROG_NAME,
        description=PROG_DESC,
        epilog=PROG_EPILOG,
        formatter_class=RawDescriptionHelpFormatter,
    )
    add_opt = o_parser.add_argument

    add_opt(
        "-a",
        "--alphabets",
        action="store_true",
        help="Don't include alphabets in the password. (Default is to include)",
    )
    add_opt(
        "-n",
        "--numbers",
        action="store_true",
        help="Don't include numbers in the password. (Default is to include)",
    )
    add_opt(
        "-p",
        "--punctuation",
        action="store_true",
        help="Don't include symbols in the password. (Default is to include)",
    )
    add_opt("-l",
            "--length",
            type=int,
            help="Length of the password. (Default is 8)",
            )

    return o_parser.parse_args()


def gen_config(cmd_opts: Namespace) -> _Config:
    """Generate config from arguments."""

    incl_letters = not cmd_opts.alphabets
    incl_digits = not cmd_opts.numbers
    incl_punct = not cmd_opts.punctuation
    p_len = cmd_opts.length or 8

    config = _Config(incl_letters, incl_digits, incl_punct, p_len)
    return config


def gen_passwd() -> str:
    """Wrapper function for putting all things together."""

    options = parse_opts()
    config = gen_config(options)
    passwd: str = _gen_passwd(config)

    return passwd


def main():
    passwd = gen_passwd()
    print(f"Password: {passwd}")


if __name__ == "__main__":
    main()
```
#####################################################

# Name: pwgen
# Author: Muhammad Altaaf <[email protected]>
# Description: A random password generator in your
# toolset.

#####################################################

from __future__ import annotations

import secrets
import string
import sys
import typing
from argparse import ArgumentParser, RawDescriptionHelpFormatter
from dataclasses import dataclass

if typing.TYPE_CHECKING:
    from argparse import Namespace

PROG_NAME = "pwgen"
PROG_DESC = """
██████╗ ██╗    ██╗ ██████╗ ███████╗███╗   ██╗
██╔══██╗██║    ██║██╔════╝ ██╔════╝████╗  ██║
██████╔╝██║ █╗ ██║██║  ███╗█████╗  ██╔██╗ ██║
██╔═══╝ ██║███╗██║██║   ██║██╔══╝  ██║╚██╗██║
██║     ╚███╔███╔╝╚██████╔╝███████╗██║ ╚████║
╚═╝      ╚══╝╚══╝  ╚═════╝ ╚══════╝╚═╝  ╚═══╝

A random password generator in your toolset.
"""

PROG_VERSION = "1.1.0"
PROG_AUTHOR = "Muhammad Altaaf"
PROG_AUTHOR_CONTACT = "[email protected]"
PROG_EPILOG = f"""\
Version {PROG_VERSION}.
Written by {PROG_AUTHOR} <{PROG_AUTHOR_CONTACT}>.
"""


@dataclass(frozen=True)
class _Config:
    letters: bool = True
    digits: bool = True
    punct: bool = True
    length: int = 8

    def __post_init__(self):
        if not (self.letters or self.digits or self.punct):
            print(
                "At least one of the three components (alphabets, numbers or \
                symbols) must be allowed",
                file=sys.stderr,
            )
            sys.exit(1)


def _gen_passwd(config: _Config) -> str:
    """The main password generator."""

    passwd_len = config.length
    # string to get password characters from
    base = ""
    # the password
    passwd = ""

    if config.letters:
        base += string.ascii_letters
    if config.digits:
        base += string.digits
    if config.punct:
        base += string.punctuation

    for _ in range(passwd_len):
        while (char := secrets.choice(base)) == "\\":
            continue
        passwd += char

    return passwd


def parse_opts() -> Namespace:
    """Parse command line options and return Namespace object."""

    o_parser = ArgumentParser(
        prog=PROG_NAME,
        description=PROG_DESC,
        epilog=PROG_EPILOG,
        formatter_class=RawDescriptionHelpFormatter,
    )
    add_opt = o_parser.add_argument

    add_opt(
        "-a",
        "--alphabets",
        action="store_true",
        help="Don't include alphabets in the password. (Default is to include)",
    )
    add_opt(
        "-n",
        "--numbers",
        action="store_true",
        help="Don't include numbers in the password. (Default is to include)",
    )
    add_opt(
        "-p",
        "--punctuation",
        action="store_true",
        help="Don't include symbols in the password. (Default is to include)",
    )
    add_opt("-l",
            "--length",
            type=int,
            help="Length of the password. (Default is 8)",
            )

    return o_parser.parse_args()


def gen_config(cmd_opts: Namespace) -> _Config:
    """Generate config from arguments."""

    incl_letters = not cmd_opts.alphabets
    incl_digits = not cmd_opts.numbers
    incl_punct = not cmd_opts.punctuation
    p_len = cmd_opts.length or 8

    config = _Config(incl_letters, incl_digits, incl_punct, p_len)
    return config


def gen_passwd() -> str:
    """Wrapper function for putting all things together."""

    options = parse_opts()
    config = gen_config(options)
    passwd: str = _gen_passwd(config)

    return passwd


def main():
    passwd = gen_passwd()
    print(f"Password: {passwd}")


if __name__ == "__main__":
    main()
```
#####################################################

# Name: pwgen
# Author: Muhammad Altaaf <[email protected]>
# Description: A random password generator in your
# toolset.

#####################################################

from __future__ import annotations

import secrets
import string
import sys
import typing
from argparse import ArgumentParser, RawDescriptionHelpFormatter
from dataclasses import dataclass

if typing.TYPE_CHECKING:
    from argparse import Namespace

PROG_NAME = "pwgen"
PROG_DESC = """
██████╗ ██╗    ██╗ ██████╗ ███████╗███╗   ██╗
██╔══██╗██║    ██║██╔════╝ ██╔════╝████╗  ██║
██████╔╝██║ █╗ ██║██║  ███╗█████╗  ██╔██╗ ██║
██╔═══╝ ██║███╗██║██║   ██║██╔══╝  ██║╚██╗██║
██║     ╚███╔███╔╝╚██████╔╝███████╗██║ ╚████║
╚═╝      ╚══╝╚══╝  ╚═════╝ ╚══════╝╚═╝  ╚═══╝

A random password generator in your toolset.
"""

PROG_VERSION = "1.1.0"
PROG_AUTHOR = "Muhammad Altaaf"
PROG_AUTHOR_CONTACT = "[email protected]"
PROG_EPILOG = f"""\
Version {PROG_VERSION}.
Written by {PROG_AUTHOR} <{PROG_AUTHOR_CONTACT}>.
"""


@dataclass(frozen=True)
class _Config:
    letters: bool = True
    digits: bool = True
    punct: bool = True
    length: int = 8

    def __post_init__(self):
        if not (self.letters or self.digits or self.punct):
            print(
                "At least one of the three components (alphabets, numbers or \
                symbols) must be allowed",
                file=sys.stderr,
            )
            sys.exit(1)


def _gen_passwd(config: _Config) -> str:
    """The main password generator."""

    passwd_len = config.length
    # string to get password characters from
    base = ""
    # the password
    passwd = ""

    if config.letters:
        base += string.ascii_letters
    if config.digits:
        base += string.digits
    if config.punct:
        base += string.punctuation

    for _ in range(passwd_len):
        while (char := secrets.choice(base)) == "\\":
            continue
        passwd += char

    return passwd


def parse_opts() -> Namespace:
    """Parse command line options and return Namespace object."""

    o_parser = ArgumentParser(
        prog=PROG_NAME,
        description=PROG_DESC,
        epilog=PROG_EPILOG,
        formatter_class=RawDescriptionHelpFormatter,
    )
    add_opt = o_parser.add_argument

    add_opt(
        "-a",
        "--alphabets",
        action="store_true",
        help="Don't include alphabets in the password. (Default is to include)",
    )
    add_opt(
        "-n",
        "--numbers",
        action="store_true",
        help="Don't include numbers in the password. (Default is to include)",
    )
    add_opt(
        "-p",
        "--punctuation",
        action="store_true",
        help="Don't include symbols in the password. (Default is to include)",
    )
    add_opt("-l",
            "--length",
            type=int,
            help="Length of the password. (Default is 8)",
            )

    return o_parser.parse_args()


def gen_config(cmd_opts: Namespace) -> _Config:
    """Generate config from arguments."""

    incl_letters = not cmd_opts.alphabets
    incl_digits = not cmd_opts.numbers
    incl_punct = not cmd_opts.punctuation
    p_len = cmd_opts.length or 8

    config = _Config(incl_letters, incl_digits, incl_punct, p_len)
    return config


def gen_passwd() -> str:
    """Wrapper function for putting all things together."""

    options = parse_opts()
    config = gen_config(options)
    passwd: str = _gen_passwd(config)

    return passwd


def main():
    passwd = gen_passwd()
    print(f"Password: {passwd}")


if __name__ == "__main__":
    main()
Source Link

Writing a random password generator

I have spent some time with python. I got an idea of creating a random password generator. It generates passwords consisting of random characters. The user can exclude different types of characters (letters, numbers, symbols) from the generated password and can customize the length of the generated password. The code consists of a single module, by the way. I am using python 3.13.0-rc1, if that is necessary. I am new here, so please pardon and mention if there is any mistake. Here is my main.py:

#####################################################

# Name: pwgen
# Author: Muhammad Altaaf <[email protected]>
# Description: A random password generator in your
# toolset.

#####################################################

from __future__ import annotations

import secrets
import string
import sys
import typing
from argparse import ArgumentParser, RawDescriptionHelpFormatter
from dataclasses import dataclass

if typing.TYPE_CHECKING:
    from argparse import Namespace

PROG_NAME = "pwgen"
PROG_DESC = """
██████╗ ██╗    ██╗ ██████╗ ███████╗███╗   ██╗
██╔══██╗██║    ██║██╔════╝ ██╔════╝████╗  ██║
██████╔╝██║ █╗ ██║██║  ███╗█████╗  ██╔██╗ ██║
██╔═══╝ ██║███╗██║██║   ██║██╔══╝  ██║╚██╗██║
██║     ╚███╔███╔╝╚██████╔╝███████╗██║ ╚████║
╚═╝      ╚══╝╚══╝  ╚═════╝ ╚══════╝╚═╝  ╚═══╝

A random password generator in your toolset.
"""

PROG_VERSION = "1.1.0"
PROG_AUTHOR = "Muhammad Altaaf"
PROG_AUTHOR_CONTACT = "[email protected]"
PROG_EPILOG = f"""\
Version {PROG_VERSION}.
Written by {PROG_AUTHOR} <{PROG_AUTHOR_CONTACT}>.
"""


@dataclass(frozen=True)
class _Config:
    letters: bool = True
    digits: bool = True
    punct: bool = True
    length: int = 8

    def __post_init__(self):
        if not (self.letters or self.digits or self.punct):
            print(
                "At least one of the three components (alphabets, numbers or \
                symbols) must be allowed",
                file=sys.stderr,
            )
            sys.exit(1)


def _gen_passwd(config: _Config) -> str:
    """The main password generator."""

    passwd_len = config.length
    # string to get password characters from
    base = ""
    # the password
    passwd = ""

    if config.letters:
        base += string.ascii_letters
    if config.digits:
        base += string.digits
    if config.punct:
        base += string.punctuation

    for _ in range(passwd_len):
        while (char := secrets.choice(base)) == "\\":
            continue
        passwd += char

    return passwd


def parse_opts() -> Namespace:
    """Parse command line options and return Namespace object."""

    o_parser = ArgumentParser(
        prog=PROG_NAME,
        description=PROG_DESC,
        epilog=PROG_EPILOG,
        formatter_class=RawDescriptionHelpFormatter,
    )
    add_opt = o_parser.add_argument

    add_opt(
        "-a",
        "--alphabets",
        action="store_true",
        help="Don't include alphabets in the password. (Default is to include)",
    )
    add_opt(
        "-n",
        "--numbers",
        action="store_true",
        help="Don't include numbers in the password. (Default is to include)",
    )
    add_opt(
        "-p",
        "--punctuation",
        action="store_true",
        help="Don't include symbols in the password. (Default is to include)",
    )
    add_opt("-l",
            "--length",
            type=int,
            help="Length of the password. (Default is 8)",
            )

    return o_parser.parse_args()


def gen_config(cmd_opts: Namespace) -> _Config:
    """Generate config from arguments."""

    incl_letters = not cmd_opts.alphabets
    incl_digits = not cmd_opts.numbers
    incl_punct = not cmd_opts.punctuation
    p_len = cmd_opts.length or 8

    config = _Config(incl_letters, incl_digits, incl_punct, p_len)
    return config


def gen_passwd() -> str:
    """Wrapper function for putting all things together."""

    options = parse_opts()
    config = gen_config(options)
    passwd: str = _gen_passwd(config)

    return passwd


def main():
    passwd = gen_passwd()
    print(f"Password: {passwd}")


if __name__ == "__main__":
    main()
```