重写密码生成器

密码政策


密码脱离政治


我感觉已经编写了五次生成密码的功能。而且他每次都做不同的事情。原因是不同项目和工具的密码要求不同。不会有复杂的代码,只有昨天提供给我的一个简单的新解决方案的摘要。


让我们从简单的密码要求开始:


  • 必须是任意长度
  • 必须包含任何印刷字符

import string
import random
from typing import List

def generate_password(length: int) -> str:
     """
     Generate a password of a given `length`.
     """
     result: List[str] = []
     choices = string.printable #    ,    
     while len(result) < length:
         symbol = random.choice(string.printable)
         result.append(symbol)
     return "".join(result)

我们尝试:


>>> generate_password(8)
... "1{k]/2)h"
>>> generate_password(13)
... "9ar|&:a+U]Il$"

好了,任务完成了,我们可以和猫一起看照片,直到工作日结束。


突然的政治


, , MyDB . , :


  • 8
  • - (!&? )
  • , bash-

, . :


  • , , -
  • ,


好的,这已经很复杂了,所以让我们从一个函数开始,该函数generate_random_string将简单地根据所提供的内容生成随机字符串。


import string
import random
from typing import List

def generate_random_string(length: int, *choices: str) -> str:
    """
    Generate a string of a given `length`.

    The result has at least one symbol from each of `choices` if `length` allows.

    Arguments:
        length -- Result string length.
        choices -- Strings with available symbols.
    """
    if not choices:
        #        ,    
        choices = (string.ascii_letters, ) 

    #      
    all_choices = "".join(choices)
    result: List[str] = []
    choice_index = 0
    while len(result) < length:
        #      , 
        #        
        if choice_index < len(choices):
            symbol = random.choice(choices[choice_index])
            result.append(symbol)
            choice_index += 1
            continue

        #        
        symbol = random.choice(all_choices)
        result.append(symbol)

    #       
    random.shuffle(result)
    return "".join(result)

因此,让我们尝试:


>>> #    
>>> generate_random_string(8, string.digits)
... "59197550"
>>> #       
>>> generate_random_string(8, string.ascii_letters, "!") 
... "vIOWXN!o"

太好了,是时候实际生成满足我们所有要求的密码了。


def generate_mydb_password(length: int) -> str:
    """
    Generate a random password for MyDB of a given `length`.

    The result has at least:
    - one uppercase letter
    - one lowercase letter
    - one digit
    - one special character

    Raises:
        ValueError -- If `length` is lesser than 8.
    """
    if length < 8:
        raise ValueError("Password length should be at least 8")

    return generate_random_string(
        length,
        string.ascii_uppercase, #      
        string.ascii_lowercase, #  
        string.digits, #  
        "!&?", #  -,    
    )

仅检查以下内容:


>>> generate_mydb_password(8)
... "P?P1&7zL"
>>> generate_mydb_password(13)
... "tR!QslK!Sl7EO"
>>> generate_mydb_password(2)
... ValueError: Password length should be at least 8


我们编写了一个易于理解的随机密码生成器,但到工作日结束还有很多时间。如果对该库不信任random,则可以将其替换为所需的库


感谢您的关注!

Source: https://habr.com/ru/post/undefined/


All Articles