Att*_*emi 5 multithreading rust rayon
我正在制作一个通过并行化暴力破解密码的程序。目前,要破解的密码已经以纯文本形式提供,我只是试图暴力破解它。
我有一个名为的函数generate_char_array(),它基于整数种子,转换基数并返回一个u8字符切片以尝试和检查。首先遍历字母表查找 1 个字符串,然后查找 2 个字符串,依此类推。
let found_string_index = (0..1e12 as u64).into_par_iter().find_any(|i| {
let mut array = [0u8; 20];
let bytes = generate_char_array(*i, &mut array);
return &password_bytes == &bytes;
});
Run Code Online (Sandbox Code Playgroud)
使用找到的字符串索引(或更确切地说种子整数),我可以生成找到的字符串。
问题是 Rayon 对我来说并行化的方式是将任意大整数范围分割成thread_count-large 切片(例如,对于 4 个线程,0..2.5e11、2.5e11..5e11 等)。这不好,因为范围的末尾是任意超大密码长度(10+,我不知道),而大多数密码(包括我倾向于尝试的固定“zzzzz”)都短得多,因此我得到的是第一个线程完成所有工作,其余线程只是浪费时间测试太长的密码和同步;结果实际上比单线程性能慢。
我怎样才能将任意大范围(实际上不必有结束)分割成范围块,并让每个线程在块中找到?这将使不同线程中的工作人员真正有用。
首先遍历字母表查找 1 个字符串,然后查找 2 个字符串
您希望对数据处理进行一些排序,但 Rayon 的重点是并行进行。
相反,使用常规迭代器顺序增加长度,然后在特定长度内使用并行迭代器来快速处理该长度的所有值。
由于您没有为可运行的示例提供足够的代码,因此我进行了粗略的近似以显示此类解决方案的一般形状:
extern crate rayon;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use std::ops::RangeInclusive;
type Seed = u8;
const LENGTHS: RangeInclusive<usize> = 1..=3;
const SEEDS: RangeInclusive<Seed> = 0..=std::u8::MAX;
fn find<F>(test_password: F) -> Option<(usize, Seed)>
where
F: Fn(usize, Seed) -> bool + Sync,
{
// Rayon doesn't support RangeInclusive yet
let seeds: Vec<_> = SEEDS.collect();
// Step 1-by-1 through the lengths, sequentially
LENGTHS.flat_map(|length| {
// In parallel, investigate every value in this length
// This doesn't do that, but it shows how the parallelization
// would be introduced
seeds
.par_iter()
.find_any(|&&seed| test_password(length, seed))
.map(|&seed| (length, seed))
}).next()
}
fn main() {
let pass = find(|l, s| {
println!("{}, {}", l, s);
// Actually generate and check the password based on the search criteria
l == 3 && s == 250
});
println!("Found password length and seed: {:?}", pass);
}
Run Code Online (Sandbox Code Playgroud)
这可能会在每个长度结束时“浪费”一点时间,因为平行线程在旋转回下一个长度之前会逐个向下旋转,但这似乎不太可能是主要问题。
| 归档时间: |
|
| 查看次数: |
3278 次 |
| 最近记录: |