Как рассчитать процент комбинаций? - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть этот генератор паролей, который вычисляет комбинацию длиной от 2 до 6 символов из списка, содержащего маленькие буквы, заглавные буквы и цифры (без 0) - вместе 61 символ.

Все, что мне нужно, это показать процент (с шагом 5) уже созданных комбинаций. Я попытался вычислить все комбинации выбранной длины, из этого числа граничное значение (5-шаговые значения) и подсчитать каждую комбинацию, записанную в текстовом файле, и когда, когда количество комбинаций соответствует граничному значению, выведите xxx % completed, но этот код не работает.

Знаете ли вы, как легко показать процент, пожалуйста?

Извините за мой английский sh, я не являюсь носителем языка.

Спасибо всем!

def pw_gen(characters, length):

    """generate all characters combinations with selected length and export them to a text file"""

    # counting number of combinations according to a formula in documentation
    k = length
    n = len(characters) + k - 1
    comb_numb = math.factorial(n)/(math.factorial(n-length)*math.factorial(length))

    x = 0

    # first value
    percent = 5

    # step of percent done to display
    step = 5

    # 'step' % of combinations
    boundary_value = comb_numb/(100/step)

    try:
        # output text file
        with open("password_combinations.txt", "a+") as f:
            for p in itertools.product(characters, repeat=length):
                combination = ''.join(p)

                # write each combination and create a new line
                f.write(combination + '\n')
                x += 1

                if boundary_value <= x <= comb_numb:
                    print("{} % complete".format(percent))
                    percent += step
                    boundary_value += comb_numb/(100/step)

                elif x > comb_numb:
                    break

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

Прежде всего - я думаю, что вы используете неправильную формулу для комбинаций, потому что itertools.product создает вариации с повторением, поэтому правильная формула n ^ k (n в степени k).

Кроме того, вы Слишком сложный расчет процентов немного. Я только что изменил ваш код, чтобы он работал как положено.

import math
import itertools

def pw_gen(characters, length):
    """generate all characters combinations with selected length and export them to a text file"""

    k = length
    n = len(characters)
    comb_numb = n ** k

    x = 0
    next_percent = 5
    percent_step = 5

    with open("password_combinations.txt", "a+") as f:
        for p in itertools.product(characters, repeat=length):
            combination = ''.join(p)

            # write each combination and create a new line
            f.write(combination + '\n')
            x += 1

            percent = 100.0 * x / comb_numb
            if percent >= next_percent:
                print(f"{next_percent} % complete")
                while next_percent < percent:
                    next_percent += percent_step

Сложная часть - while l oop, которая гарантирует, что все будет хорошо работать для очень маленьких наборов (где одна комбинация больше, чем step процент результатов).

0 голосов
/ 20 февраля 2020

Удалено try:, поскольку вы не обрабатываете ошибки с expect. Также удалено elif:, это условие никогда не выполняется. Кроме того, ваша формула для comb_numb неверна, так как вы генерируете комбинации с повторением. С этими изменениями ваш код хорош.

import math, iterations, string
def pw_gen(characters, length):

    """generate all characters combinations with selected length and export them to a text file"""

    # counting number of combinations according to a formula in documentation
    comb_numb = len(characters) ** k

    x = 0

    # first value
    percent = 5

    # step of percent done to display
    step = 5

    # 'step' % of combinations
    boundary_value = comb_numb/(100/step)
    # output text file
    with open("password_combinations.txt", "a+") as f:
        for p in itertools.product(characters, repeat=length):
            combination = ''.join(p)
            # write each combination and create a new line
            f.write(combination + '\n')
            x += 1
            if boundary_value <= x:
                print("{} % complete".format(percent))
                percent += step
                boundary_value += comb_numb/(100/step)

pw_gen(string.ascii_letters, 4)
...