사람이 읽을 수 있는 암호

14136 단어 pythondjango

소개



Django 애플리케이션의 경우 웹사이트에 가입하는 사용자의 비밀번호를 만들어야 했습니다. 암호 생성은 비교적 쉬울 수 있습니다.

이 기능을 살펴보십시오.

def generate_password(length=10):
 return "".join(
        random.choice(string.ascii_letters + string.digits) for _ in range(length)
    )


결과입니다

>>> print(generate_raw_password())
>>> B61CbF9GdW


이것은 안전하지만 기억하기 어렵습니다.

보다 사용자 친화적으로 만들기 위해 https://xkpasswd.net/s/ 에서 영감을 받은 함수를 만들어야겠다고 생각했습니다. 이 웹사이트는 사람이 읽을 수 있는 안전한 비밀번호를 생성합니다. 예는 3~shoes~FOUND@이며 이것은 이전 방법보다 훨씬 더 사람이 읽을 수 있습니다.

세부



사람이 읽을 수 있는 암호를 만드는 방법은 무엇입니까?

단어 목록



단어 목록부터 시작해야 했습니다. Wordle이 매우 인기가 있기 때문에 5글자 단어 목록을 찾는 것이 그리 어렵지 않습니다. 많은 Worlde 복제본이 있으며 GitHub에는 이러한 목록이 있는 Wordle 복제본이 많이 있습니다. 그러나 모든 정직에서 원래 Wordle의 출처로 이동하여 해당 목록을 얻을 수 있는지 확인하십시오.

뉴욕 타임즈 워드



NY Times는 원래 Wordle을 구입했으며 소스는 더 이상 사용할 수 없습니다. 약간의 해킹으로 여전히 목록을 얻을 수 있습니다.
이 링크를 엽니다: https://www.nytimes.com/games/wordle/main.bd4cb59c.js . ,Oa=를 검색하면 목록이 시작됩니다. 이 목록에는 약 10,000개의 단어가 있습니다. 목록을 확인했을 때 사람들이 약간 부적절하다고 생각할 수 있는 몇 가지 단어를 찾았습니다. d*cks 그리고 그건 새가 아닙니다. b**by.

컴퓨터에서



5글자 단어 목록을 생성하는 다른 방법을 찾았습니다. 대부분의 Linux 기반 시스템 및 Mac에는 시스템에 단어 목록이 있습니다/usr/share/dict/words. 5글자 단어를 모두 추출하기 위해 Perl에서 간단한 한 줄짜리 코드를 작성할 수 있습니다.

perl -nle 'print if /^[a-z]{5}$/' /usr/share/dict/words > words5.txt


그리고 거기에 목록이 있습니다. 불행히도 전체 목록에는 1934년의 단어가 포함되어 있으며 목록에서 더 이상 사용하지 않는 일부 단어를 찾았습니다.

스탠포드 GraphBase



Donald Knuth는 다섯 글자 단어 목록을 만들었습니다. 이 목록은 이러한 단어 간의 관계를 탐색하기 위해 다양한 조합 실험, 그래프 알고리즘 및 기타 알고리즘을 실행하는 데 사용됩니다. 목록은 공개 도메인에 있으며 5757 단어가 있습니다.

이것은 내가 지금 사람이 읽을 수 있는 암호를 만들기 위해 사용하고 있는 목록입니다.

목록 사용



단어 목록을 Python 목록에 넣는 대신 목록을 DB에 넣기로 결정했습니다. 이렇게 하면 원하는 경우 나중에 단어를 더 쉽게 추가할 수 있습니다.

모델은 매우 쉽습니다.

# code/word_model.py

class Word(models.Model):
    word = models.CharField(max_length=10, unique=True)

    def __str__(self):
        return self.word



모델을 채우는 방법은 여러분에게 맡기겠습니다.

요구 사항



암호는 다음 요구 사항을 충족해야 합니다.
  • 최소 1자리에서 최대 2자리의 비밀번호를 앞에 추가하십시오.
  • 각 단어를 특수 문자로 구분합니다.
  • 각 단어는 모두 소문자, 모두 대문자 또는 대문자로 변환됩니다.
  • 암호 내에서 단어를 반복하지 마십시오.

  • 또한 원하는 만큼 많은 단어를 사용할 수 있는 유연성을 갖고 싶습니다. 기본적으로 3개를 사용하고 두 개 미만의 단어는 허용하지 않습니다.

    암호




    # code/password.py
    
    import random
    
    from models import Word
    
    
    def create_password(words=3):
        """
        Generate a password
    
        Parameters
        ----------
        words: int
    
        Returns
        -------
        str
        """
        if words < 2:
            raise ValueError
        numbers = random.sample(range(1, 99), 2)
        special_character = "!@$%^&*-_+=:|~?/.;"
        separator = random.sample(special_character, words - 1)
        selected_words = get_random_words(words)
        password = str(numbers[0])
        for step in range(words - 1):
            password = password + transform_word(selected_words[step]) + separator[step]
        password = password + transform_word(selected_words[words - 1]) + str(numbers[1])
        return password
    
    
    def get_random_words(amount):
        """
        Get a list of unique words
    
        Parameters
        ----------
        amount: int
    
        Returns
        -------
        list of str
    
        """
        total_word_count = Word.objects.all().count()
        ids = random.sample(range(1, total_word_count), amount)
        selected_words = list(
            Word.objects.filter(id__in=ids).values_list("word", flat=True)
        )
        while len(selected_words) < amount:
            id = random.randint(1, total_word_count)
            if id in ids:
                continue
            selected_word = Word.objects.get(id=id)
            if selected_word:
                selected_words.append(selected_word.word)
        return selected_words
    
    
    def transform_word(word):
        """
        Transform a string
    
        Parameters
        ----------
        word: str
    
        Returns
        -------
        str
        """
        transform = random.randint(1, 3)
        if transform == 1:
            transformed_word = word.capitalize()
        elif transform == 2:
            transformed_word = word.lower()
        elif transform == 3:
            transformed_word = word.upper()
        return transformed_word
    
    


    이 기능으로 생성된 암호의 몇 가지 예:

    73PYGMY|Glens~Naiad33
    29radar|bylaw%SWATH19
    5plant.Cages+Dizzy54
    72DOUGH!Yolks-hooch28
    92FLESH^churl%genet69
    


    결론



    이 코드를 사용하면 사람이 읽을 수 있는 암호를 만들 수 있습니다. 사용된 단어를 데이터베이스에 추가하여 쉽게 확장할 수 있습니다.

    메모
  • string.punctuation 대신 내가 선택한 특수 문자를 사용합니다. 따옴표와 같은 해당 목록의 특정 문자를 원하지 않았습니다.

  • 참조
  • NY Times Wordle: https://www.nytimes.com/games/wordle/index.html
  • 스탠포드 GraphBase: https://www-cs-faculty.stanford.edu/~knuth/sgb.html

  • 오타를 찾았습니까?



    이 블로그 게시물에서 오타, 개선할 수 있는 문장 또는 업데이트해야 할 사항을 발견한 경우 git 저장소를 통해 액세스하고 풀 요청을 할 수 있습니다. 댓글을 게시하는 대신 직접 이동하여 변경 사항이 포함된 새로운 풀 리퀘스트를 여세요.




    Colin Lloyd의 사진 - https://unsplash.com/photos/62OEfKjU1Vs

    좋은 웹페이지 즐겨찾기