优化跨文件匹配明文的贪心算法以生成更优攻击链的技术求助
优化跨文件匹配明文的贪心算法以生成更优攻击链的技术求助
我现在有下面这段代码:
import os from collections import defaultdict import re # Parameters X_percent = 0.93 # Desired coverage percentage (e.g., 93%) lambda_penalty = 500 # Adjusted penalty max_attack_time = 3600 # Maximum allowed execution time per attack in seconds max_total_time = 20 * 3600 # Maximum total execution time in seconds (15 hours) min_new_plains = 10 # Minimum number of new plains an attack must cover max_plain_weight = 5 # Maximum weight assigned to any plain set_a_directory = '/root/setA/' # Directory containing Set A files file_b_path = '/root/h.txt' # Path to File B # Step 1: Read File B and assign unique IDs to plains plain_to_id = {} id_to_plain = {} with open(file_b_path, 'r') as f: for line in f: plain = line.strip() if plain not in plain_to_id: plain_id = len(plain_to_id) plain_to_id[plain] = plain_id id_to_plain[plain_id] = plain total_plains = len(plain_to_id) print(f"Total number of plains in File B: {total_plains}") # Step 2: Process Set A files and build data structures attack_info = [] plain_to_attacks = defaultdict(set) # Maps plain ID to set of attack indices # Regular expression to extract time from file name time_pattern = re.compile(r'^(\d+)_') # Iterate over each file in Set A for file_name in os.listdir(set_a_directory): file_path = os.path.join(set_a_directory, file_name) # Extract execution time from file name time_match = time_pattern.match(file_name) if not time_match: continue # Skip files that don't match the pattern execution_time = int(time_match.group(1)) if execution_time > max_attack_time: continue # Exclude attacks over the maximum allowed time with open(file_path, 'r') as f: lines = f.readlines() if not lines: continue # Skip empty files attack_command = lines[0].strip() plains_covered = set() for line in lines[1:]: parts = line.strip().split(':') if not parts: continue plain = parts[0].strip() if plain in plain_to_id: plain_id = plain_to_id[plain] plains_covered.add(plain_id) plain_to_attacks[plain_id].add(len(attack_info)) # Index of this attack attack_info.append({ 'command': attack_command, 'time': execution_time, 'plains': plains_covered, 'index': len(attack_info) }) num_attacks = len(attack_info) print(f"Total number of attacks in Set A after filtering: {num_attacks}") # Step 3: Compute the number of attacks covering each plain (f_p) plain_cover_count = {} for plain_id in plain_to_id.values(): cover_count = len(plain_to_attacks[plain_id]) plain_cover_count[plain_id] = cover_count # Step 4: Assign weights to plains with a maximum weight plain_weights = {} for plain_id, f_p in plain_cover_count.items(): if f_p > 0: plain_weights[plain_id] = min(1.0 / f_p, max_plain_weight) else: plain_weights[plain_id] = max_plain_weight # Step 5: Implement the weighted greedy algorithm with adjusted efficiency total_plains_needed = int(total_plains * X_percent) print(f"Number of plains needed for {X_percent*100}% coverage: {total_plains_needed}") covered_plains = set() selected_attacks = [] remaining_attacks = set(range(num_attacks)) total_execution_time = 0 while len(covered_plains) < total_plains_needed and remaining_attacks: best_efficiency = -1 best_attack = None for i in remaining_attacks: attack = attack_info[i] new_plains = attack['plains'] - covered_plains if len(new_plains) < min_new_plains: continue # Skip attacks that cover too few new plains # Calculate W_i (sum of weights of new plains) W_i = sum(plain_weights[p] for p in new_plains) # Adjusted Efficiency E_i efficiency = (W_i * len(new_plains)) / (attack['time'] + lambda_penalty) if efficiency > best_efficiency: best_efficiency = efficiency best_attack = i if best_attack is None: print("No further attacks can improve coverage.") break # Check if adding this attack exceeds the maximum total execution time if total_execution_time + attack_info[best_attack]['time'] > max_total_time: print("Reached maximum total execution time limit.") break # Select the attack with the highest adjusted efficiency selected_attacks.append(best_attack) covered_plains.update(attack_info[best_attack]['plains']) remaining_attacks.remove(best_attack) total_execution_time += attack_info[best_attack]['time'] # Optional: Print progress coverage_percentage = (len(covered_plains) / total_plains) * 100 print(f"Selected attack {best_attack}: Coverage {coverage_percentage:.2f}%, " f"Total Time: {total_execution_time / 3600:.2f} hours") # Step 6: Output the results print("\nSelected Attacks:") for idx in selected_attacks: attack = attack_info[idx] print(f"Attack Index: {idx}") print(f"Command: {attack['command']}") print(f"Time: {attack['time']} seconds") print(f"Plains Covered: {len(attack['plains'])}") print("-----------------------------") final_coverage = (len(covered_plains) / total_plains) * 100 print(f"Final Coverage: {final_coverage:.2f}%") print(f"Total Execution Time: {total_execution_time / 3600:.2f} hours") print(f"Total Attacks Selected: {len(selected_attacks)}")
我有一个存储文件的目录,我们称之为Set A文件。每个文件的文件名格式是「运行时间_RandomString.txt」,文件第一行是一条命令/攻击,剩下的行是由该命令/攻击生成的两列数据(另一程序的输出结果),左侧是我们所说的明文,右侧内容可以忽略。另外我还有一个单独的文件,称之为File B,里面有12.1万行明文。
我的目标是用这个Python程序找到一组命令/攻击链,使得它们对应的文件中的明文能够以最短时间覆盖File B中明文的一定比例。Set A文件中的明文重叠度很高,而且我有3600个文件,总共有2.5亿行数据,所以时间和计算资源都是需要考虑的问题,这也是我使用贪心算法的原因。
但目前我的Python代码输出的结果不够理想——它选择了太多的攻击链,总运行时间也过高。我想知道有没有办法优化这个程序,让生成的攻击链更「最优」一些。我有一台192核、256GB内存的机器,所以不介意等待几个小时的计算时间。谢谢!
备注:内容来源于stack exchange,提问作者jayboy
相关产品推荐
相关产品推荐

