Я и мой друг хотим создать сценарий, который дает нам все возможные перестановки шестизначного кода, состоящего из 36 буквенно-цифровых символов (0-9 и az) в алфавитном порядке, а затем мы сможем увидеть их в файле .txt. .

И я хочу, чтобы он использовал весь ЦП и ОЗУ, чтобы он занимал меньше времени для выполнения задачи.

Пока что это код:

import random
charset = "0123456789abcdefghijklmnopqrstuvwxyz"
links = []
file = open("codes.txt", "a")

for g in range(0, 36**6):
    key = ""
    base = ""
    print(str(g))
    for i in range(0, 6):
        char = random.choice(charset)
        key += char
    base += key
    file.write(base + "\n")

file.close()

Этот код случайным образом генерирует комбинации и немедленно записывает их в файл .txt, одновременно распечатывая количество кодов, которые он уже создал, но не в алфавитном порядке (необходимо сделать это потом), и это занимает слишком много времени.

Как можно улучшить код, чтобы получить желаемый результат?

Спасибо @ R0Best за лучший ответ

1
TheChris1215 25 Сен 2021 в 20:14

6 ответов

Лучший ответ

Самый быстрый способ, который я могу придумать, - использовать pypy3 https://www.pypy.org/ с этим кодом :

import functools
import time

@functools.lru_cache(maxsize=128)
def a():
    cs, cl = "0123456789abcdefghijklmnopqrstuvwxyz", []
    for letter in cs:
        cl.append(letter)
    ct = tuple(cl)
    with open("codes.txt", "w") as file:
        for p1 in ct:
            for p2 in ct:
                for p3 in ct:
                    for p4 in ct:
                        for p5 in ct:
                            for p6 in ct:
                                file.write(f"{p1}{p2}{p3}{p4}{p5}{p6}\n")
        file.close()
start = time.time()
a()
print(f"Done! \nTook {start - time.time()} seconds!")

Он пишет со скоростью около 10-15 МБ / с. Общий размер файла, как я полагаю, составляет около 15 ГБ, поэтому для создания потребуется 990-1500 секунд. Результаты получены на vm of unraid с 1 ядром серверного процессора с частотой 3,4 ГГц, со старым sdd sata3, вы, вероятно, получите лучшие результаты с накопителем NVME и более быстрым одноядерным процессором.

0
R0Best 25 Сен 2021 в 18:14

Случайно Может быть очень неэффективным. Ты можешь попробовать :

from itertools import permutations
from pandas import Series
charset = list("0123456789abcdefghijklmnopqrstuvwxyz")
links = []
file = open("codes.txt", "a")
comb = permutations(charset,6)
comb = list(comb)
comb = list(map(lambda x:return ''.join(x),comb))
mySeries = Series(comb)
mySeries = mySeries.sort_values()

base = ""
for k in mySeries:
    base += k
file.write(base + "\n")

file.close()
0
Khushal Jangid 25 Сен 2021 в 17:33

Вы можете использовать itertools.permutaions из библиотеки по умолчанию itertools. Вы также можете указать количество символов в комбинации.

from itertools import permutations
charset = "0123456789abcdefghijklmnopqrstuvwxyz"

c = permutations(charset, 6)

with open('code.txt', 'w') as f:
    for i in c:
        f.write("".join(i) + '\n')

Запускается на моем компьютере примерно за 200 миллисекунд для создания списка перестановок, а затем тратит много времени на запись в файл

0
CoderTang 25 Сен 2021 в 17:39

Для перестановок это поможет:

from itertools import permutations
charset = "0123456789abcdefghijklmnopqrstuvwxyz"
links = []
with open("codes.txt", "w") as f:
    for permutation in permutations(charset, 6):
        f.write(''.join(permutation) + '\n')

К вашему сведению, это создаст файл размером 7,8 гигабайта

Для комбинаций это поможет:

from itertools import combinations
charset = "0123456789abcdefghijklmnopqrstuvwxyz"
links = []
with open("codes.txt", "w") as f:
    for comb in combinations(charset, 6):
        f.write(''.join(comb)+ '\n')

К вашему сведению, это создаст файл размером 10,8 мегабайт

0
ori6151 25 Сен 2021 в 17:47

Первым делом; Есть способы сделать это лучше, но я хочу написать что-нибудь ясное и понятное.

Псевдокод:

base = "";
for(x1=0; x1<charset.length(); x1++)
    for(x2=0; x2<charset.length(); x2++)
        for(x3=0; x3<charset.length(); x3++)
            .
            .
            .
        { base = charset[x1]+charset[x2]+charset[x3]+.....+charset[x6];
          file.write(base + "\n")
        }
0
Jabbar 25 Сен 2021 в 17:50

Это проблема комбинации, когда вы пытаетесь получить комбинации длины 6 из набора символов длиной 36. Это даст результат размером 36! / (30! * 6!). Вы можете направить itertools для решения такой комбинированной задачи, как ваша. Вы можете сослаться на функцию комбинирования в itertools Документация. Не рекомендуется выполнять такие интенсивные вычисления с использованием Python.

0
Sangeerththan Balachandran 25 Сен 2021 в 18:21