[英]Combinatorics algorithm for extracting subsets of lists for a password cracker
我一定很生銹,因為我無法提出解決方案。
假設我們有3個單詞列表:
list1 list2 list3
----- ----- -----
pizza red child
pasta green man
apple blue adult
pear yellow old
我需要從每個列表中選擇子集,例如:
現在,簡單的解決方案當然是了,比如說您必須將此列表分為4個工人4(我在上面稱為“選定部分”),只需將每個披薩開頭的組合發送給工人1,將意大利面發送給2,依此類推。 但是,如果您的工人比最長的列表中的元素多,那是行不通的,事情會變得復雜。
這樣就給目標列表,找到所有組合。 但是您需要將主要工作拆分為更多機器。
上面說明的簡單解決方案是,最長的列表中有4個元素,只需使用4台機器即可。 在這種情況下,它看起來像這樣:
機器1:
list1 list2 list3
----- ----- -----
pizza red child
green man
blue adult
yellow old
機器2:
list1 list2 list3
----- ----- -----
red child
pasta green man
blue adult
yellow old
機器3:
list1 list2 list3
----- ----- -----
red child
green man
apple blue adult
yellow old
機器4:
list1 list2 list3
----- ----- -----
red child
green man
blue adult
pear yellow old
但是,如果必須將工作分配到比最長列表中的元素數更多的機器上,則此方法將無效。 在這種情況下,假設您需要將工作拆分為8台機器(或每台機器兩輪中的4台機器),則必須看起來像這樣(我使用8台機器是為了簡化示例,但實際數量並非如此)好)。
機器1:
list1 list2 list3
----- ----- -----
pizza red child
green man
adult
old
機器2:
list1 list2 list3
----- ----- -----
red child
pasta green man
adult
old
機器3:
list1 list2 list3
----- ----- -----
red child
green man
apple adult
old
機器4:
list1 list2 list3
----- ----- -----
red child
green man
adult
pear old
機器5:
list1 list2 list3
----- ----- -----
pizza child
man
blue adult
yellow old
機器6:
list1 list2 list3
----- ----- -----
child
pasta man
blue adult
yellow old
機器7:
list1 list2 list3
----- ----- -----
child
man
apple blue adult
yellow old
機器8:
list1 list2 list3
----- ----- -----
child
man
blue adult
pear yellow old
如您所見,這是將最大元素為4的原始列表拆分為8台計算機的方法。 問題是,當您無法控制列表中的計算機數量/元素數量時,如何以編程方式執行此操作?
如果有1個工人,則按順序排列:
pizza red child
pizza red man
pizza red adult
pizza red old
pizza green child
pizza green man
pizza green adult
pizza green old
pizza blue child
pizza blue man
pizza blue adult
pizza blue old
pizza yellow child
pizza yellow man
pizza yellow adult
pizza yellow old
pasta red child
pasta red man
pasta red adult
pasta red old
pasta green child
pasta green man
pasta green adult
pasta green old
pasta blue child
pasta blue man
pasta blue adult
pasta blue old
pasta yellow child
pasta yellow man
pasta yellow adult
pasta yellow old
apple red child
apple red man
apple red adult
apple red old
apple green child
apple green man
apple green adult
apple green old
apple blue child
apple blue man
apple blue adult
apple blue old
apple yellow child
apple yellow man
apple yellow adult
apple yellow old
pear red child
pear red man
pear red adult
pear red old
pear green child
pear green man
pear green adult
pear green old
pear blue child
pear blue man
pear blue adult
pear blue old
pear yellow child
pear yellow man
pear yellow adult
pear yellow old
如果您有更多工人,則按范圍划分。 例如,Worker1獲得“披薩紅色孩子”-“披薩藍色孩子”。 工人2獲得“披薩藍人”-“意大利面紅大人”等
#include <vector>
#include <thread>
#include <cstdio>
using namespace std;
vector<vector<string>> lists = {{"apple", "pasta", "pear", "pizza"}, {"red", "green", "blue", "yellow"}, {"child", "man", "adult", "old"}};
const int K = 7;
long long N = 1;
std::vector<long long> calc_vector(int k){
long long remain_all = N;
long long remain_cur = N * k / K;
std::vector<long long> ret;
for(int i=0; i<lists.size(); ++i){
long long sz = lists[i].size();
long long i1 = remain_cur * sz / remain_all;
ret.push_back(i1);
remain_all /= sz;
remain_cur -= remain_all * i1;
}
return ret;
}
void work(int k){
auto v1 = calc_vector(k);
auto v2 = calc_vector(k+1);
while(v1 != v2){
printf("%d: %s-%s-%s\n", k, lists[0][v1[0]].c_str(), lists[1][v1[1]].c_str(), lists[2][v1[2]].c_str());
for(int i=v1.size()-1; i>=0; --i){
v1[i]++;
if(v1[i] != lists[i].size() || i==0) break;
else v1[i] = 0;
}
}
}
int main(){
for(auto &list : lists) N *= list.size();
vector<thread> threads;
for(int i=0; i<K; ++i) threads.push_back(thread(work, i));
for(auto &thread : threads) thread.join();
return 0;
}
如果我做對了,也許您可以嘗試替換在所選部分中選擇的元素。 例如;
披薩-紅色-兒童
然后;
意大利面-紅色-兒童
。 。 。
等等...
因此,您可以嘗試為每種可能的組合操作一個選定的部分,而不是為每種可能的組合創建新的選定部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.