本文主要介绍了一个C#编写的RAR压缩文件密码恢复工具,该程序通过加载密码字典文件,逐个尝试密码来破解受密码保护的RAR文件。
主要功能包括
1.选择RAR文件和密码字典
2.显示恢复进度
3.统计尝试密码数量和速度
4.计算剩余时间
本工具采用后台线程运行密码破解过程,可以避免UI冻结,并提供取消操作功能。
效果图
程序代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Windows.Forms; using SharpCompress.Archives; using SharpCompress.Archives.Rar; using SharpCompress.Common; using SharpCompress.Readers; namespace RarPasswordRecovery { public partial class MainForm : Form { private Backgroundworker worker; private long totalPasswords; private long testedPasswords; private Stopwatch stopwatch; private List<string> passwordList; private bool passwordFound; private string foundPassword; private bool isRunning; public MainForm() { InitializeComponent(); InitializeBackgroundWorker(); SetupUI(); } private void InitializeBackgroundWorker() { worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; worker.DoWork += Worker_DoWork; worker.ProgressChanged += Worker_ProgressChanged; worker.RunWorkerCompleted += Worker_RunWorkerCompleted; } private void SetupUI() { // 设置窗体 this.Text = "RAR密码恢复工具"; this.Size = new Size(800, 500); this.MinimumSize = new Size(600, 400); this.BackColor = Color.FromArgb(45, 45, 65); this.ForeColor = Color.White; this.FormBorderStyle = FormBorderStyle.FixedSingle; this.StartPosition = FormStartPosition.CenterScreen; // 创建控件 CreateControls(); } private void CreateControls() { // 标题标签 Label titleLabel = new Label { Text = "RAR压缩文件密码恢复", Font = new Font("Segoe UI", 16, FontStyle.Bold), AutoSize = true, Location = new Point(20, 15), ForeColor = Color.LightSkyBlue }; this.Controls.Add(titleLabel); // RAR文件选择 Label lblRarFile = new Label { Text = "RAR文件路径:", Location = new Point(20, 60), AutoSize = true }; this.Controls.Add(lblRarFile); TextBox txtRarFilePath = new TextBox { Location = new Point(120, 57), Size = new Size(500, 25), Name = "txtRarFilePath", ReadOnly = true }; this.Controls.Add(txtRarFilePath); Button btnBrowseRar = new Button { Text = "浏览...", Location = new Point(630, 55), Size = new Size(80, 25), Name = "btnBrowseRar", BackColor = Color.FromArgb(70, 70, 90), ForeColor = Color.White, FlatStyle = FlatStyle.Flat }; btnBrowseRar.FlatAppearance.BorderSize = 0; btnBrowseRar.Click += BtnBrowseRar_Click; this.Controls.Add(btnBrowseRar); // 字典文件选择 Label lblDictionary = new Label { Text = "密码字典文件:", Location = new Point(20, 100), AutoSize = true }; this.Controls.Add(lblDictionary); TextBox txtDictionaryPath = new TextBox { Location = new Point(120, 97), Size = new Size(500, 25), Name = "txtDictionaryPath", ReadOnly = true }; this.Controls.Add(txtDictionaryPath); Button btnBrowseDict = new Button { Text = "浏览...", Location = new Point(630, 95), Size = new Size(80, 25), Name = "btnBrowseDict", BackColor = Color.FromArgb(70, 70, 90), ForeColor = Color.White, FlatStyle = FlatStyle.Flat }; btnBrowseDict.FlatAppearance.BorderSize = 0; btnBrowseDict.Click += BtnBrowseDict_Click; this.Controls.Add(btnBrowseDict); // 进度条 ProgressBar progressBar = new ProgressBar { Location = new Point(20, 150), Size = new Size(690, 25), Name = "progressBar", Style = ProgressBarStyle.Continuous }; this.Controls.Add(progressBar); // 状态标签 Label lblStatus = new Label { Location = new Point(20, 185), Size = new Size(690, 20), Name = "lblStatus", Text = "就绪", TextAlign = ContentAlignment.MiddleLeft }; this.Controls.Add(lblStatus); // 统计信息 Label lblTotal = new Label { Location = new Point(20, 215), Size = new Size(200, 20), Name = "lblTotalPasswords", Text = "总密码数: 0" }; this.Controls.Add(lblTotal); Label lblTested = new Label { Location = new Point(230, 215), Size = new Size(200, 20), Name = "lblTested", Text = "已尝试: 0" }; this.Controls.Add(lblTested); Label lblSpeed = new Label { Location = new Point(440, 215), Size = new Size(200, 20), Name = "lblSpeed", Text = "速度: 0 p/s" }; this.Controls.Add(lblSpeed); // 时间信息 Label lblElapsed = new Label { Location = new Point(20, 245), Size = new Size(200, 20), Name = "lblElapsed", Text = "已用时间: 00:00:00" }; this.Controls.Add(lblElapsed); Label lblRemaining = new Label { Location = new Point(230, 245), Size = new Size(200, 20), Name = "lblRemaining", Text = "剩余时间: --:--:--" }; this.Controls.Add(lblRemaining); // 当前尝试密码 Label lblCurrent = new Label { Text = "当前尝试密码:", Location = new Point(20, 280), AutoSize = true }; this.Controls.Add(lblCurrent); TextBox txtCurrentPassword = new TextBox { Location = new Point(120, 277), Size = new Size(500, 25), Name = "txtCurrentPassword", ReadOnly = true, Font = new Font("Consolas", 10), BackColor = Color.FromArgb(30, 30, 40), ForeColor = Color.LightGreen }; this.Controls.Add(txtCurrentPassword); // 按钮 Button btnStart = new Button { Text = "开始恢复", Location = new Point(200, 320), Size = new Size(120, 35), Name = "btnStart", BackColor = Color.SeaGreen, FlatStyle = FlatStyle.Flat, Font = new Font("Segoe UI", 10, FontStyle.Bold) }; btnStart.FlatAppearance.BorderSize = 0; btnStart.Click += BtnStart_Click; this.Controls.Add(btnStart); Button btnCancel = new Button { Text = "取消", Location = new Point(340, 320), Size = new Size(120, 35), Name = "btnCancel", Enabled = false, BackColor = Color.IndianRed, FlatStyle = FlatStyle.Flat, Font = new Font("Segoe UI", 10) }; btnCancel.FlatAppearance.BorderSize = 0; btnCancel.Click += BtnCancel_Click; this.Controls.Add(btnCancel); // 法律声明 LinkLabel linkLegal = new LinkLabel { Text = "使用条款和道德声明", Location = new Point(20, 370), AutoSize = true, LinkColor = Color.LightSkyBlue, ActiveLinkColor = Color.Cyan }; linkLegal.LinkClicked += LinkLegal_LinkClicked; this.Controls.Add(linkLegal); // 状态图标 PictureBox statusIcon = new PictureBox { Location = new Point(650, 320), Size = new Size(60, 60), SizeMode = PictureBoxSizeMode.Zoom }; // 注意:在实际项目中,您需要添加自己的图标 statusIcon.BackColor = Color.Transparent; this.Controls.Add(statusIcon); } http://www.devze.com private void BtnBrowseRar_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "RAR files (*.rar)|*.rar|All files (*.*)|*.*"; openFileDialog.Title = "选择RAR文件"; if (openFileDialog.ShowDialog() == DialogResult.OK) { GetTextBox("txtRarFilePath").Text = openFileDialog.FileName; } } } private void BtnBrowseDict_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"; openFileDialog.Title = "选择密码字典文件"; if (openFileDialog.ShowDialog() == DialogResult.OK) { GetTextBox("txtDictionaryPath").Text = openFileDialog.FileName; } } } private void BtnStart_Click(object sender, EventArgs e) { TextBox txtRarFilePath = GetTextBox("txtRarFilePath"); TextBox txtDictionaryPath = GetTextBox("txtDictionaryPath"); if (string.IsNullOrWhiteSpace(txtRarFilePath.Text)) { MessageBox.Show("请选择RAR文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (string.IsNullOrWhiteSpace(txtDictionaryPath.Text)) { MessageBox.Show("请选择密码字典文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (!File.Exists(txtRarFilePath.Text)) { MessageBox.Show("选择的RAR文件不存在", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (!File.Exists(txtDictionaryPath.Text)) { MessageBox.Show("选择的字典文件不存在", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 重置UI passwordFound = false; foundPassword = null; testedPasswords = 0; isRunning = true; GetProgressBar().Value = 0; GetLabel("lblStatus").Text = "加载密码字典..."; GetLabel("lblTested").Text = "已尝试: 0"; GetLabel("lblSpeed").Text = "速度: 0 p/s"; GetLabel("lblElapsed").Text = "已用时间: 00:00:00"; GetLabel("lblRemaining").Text = "剩余时间: --:--:--"; GetTextBox("txtCurrentPassword").Text = ""; GetButton("btnStart").Enabled = false; GetButton("btnCancel").Enabled = true; try { // 读http://www.devze.com取字典文件 passwordList = File.ReadAllLines(txtDictionaryPath.Text) .Where(p => !string.IsNullOrWhiteSpace(p)) .Distinct() .ToList(); totalPasswords = passwordList.Count; if (totalPasswords == 0) { MessageBox.Show("字典文件为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); ResetUI(); return; } GetLabel("lblTotalPasswords").Text = $"总密码数: {totalPasswords:N0}"; stopwatch = Stopwatch.StartNew(); worker.RunWorkerAsync(); } catch (Exception ex) { MessageBox.Show($"读取字典文件错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); ResetUI(); } } private void Worker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; passwordFound = false; foundPassword = null; stringhttp://www.devze.com rarFilePath = GetTextBox("txtRarFilePath").Text; try { // 尝试每个密码 for (int i = 0; i < passwordList.Count; i++) { if (worker.CancellationPending) { e.Cancel = true; return; } string password = passwordList[i]; testedPasswords++; try { // 修复:使用ReaderOptions传递密码 php var options = new ReaderOptions { Password = password, LookForHeader = true, DisableCheckIncomplete = true }; // 尝试打开压缩文件 using (var archive = RarArchive.Open(rarFilePath, options)) { // 尝试访问第一个文件 var entry = archive.Entries.FirstOrDefault(); if (entry != null) { // 尝试读取少量数据 using (var stream = entry.OpenEntryStream()) { byte[] buffer = new byte[10]; stream.Read(buffer, 0, buffer.Length); // 如果成功读取数据,密码正确 passwordFound = true; foundPassword = password; return; } } } } catch (SharpCompress.Common.CryptographicException) { // 密码错误,继续尝试 } catch (InvalidFormatException) { // 密码错误或文件格式问题 } catch (Exception ex) { // 其他错误,记录并继续尝试 worker.ReportProgress(0, $"密码 '{password}' 尝试失败: {ex.Message}"); } // 每100次尝试报告一次进度 if (testedPasswords % 100 == 0) { int progress = (int)((double)testedPasswords / totalPasswords * 100); worker.ReportProgress(progress, password); } } } catch (Exception ex) { worker.ReportProgress(0, $"错误: {ex.Message}"); } } private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (e.UserState is string currentPassword) { GetTextBox("txtCurrentPassword").Text = currentPassword; } GetProgressBar().Value = e.ProgressPercentage; GetLabel("lblTested").Text = $"已尝试: {testedPasswords:N0} / {totalPasswords:N0}"; // 计算速度 double seconds = stopwatch.Elapsed.TotalSeconds; double passwordsPerSecond = seconds > 0 ? testedPasswords / seconds : 0; GetLabel("lblSpeed").Text = $"速度: {passwordsPerSecond:N1} p/s"; // 计算剩余时间 if (passwordsPerSecond > 0) { long remaining = totalPasswords - testedPasswords; TimeSpan remainingTime = TimeSpan.FromSeconds(remaining / passwordsPerSecond); GetLabel("lblRemaining").Text = $"剩余时间: {remainingTime:hh\\:mm\\:ss}"; } GetLabel("lblElapsed").Text = $"已用时间: {stopwatch.Elapsed:hh\\:mm\\:ss}"; GetLabel("lblStatus").Text = "正在尝试恢复密码..."; } private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { stopwatch.Stop(); isRunning = false; if (e.Cancelled) { GetLabel("lblStatus").Text = "操作已取消"; } else if (e.Error != null) { GetLabel("lblStatus").Text = $"错误: {e.Error.Message}"; } else if (passwordFound) { GetLabel("lblStatus").Text = "密码已找到!"; GetTextBox("txtCurrentPassword").Text = foundPassword; GetTextBox("txtCurrentPassword").ForeColor = Color.Lime; MessageBox.Show($"密码已找到: {foundPassword}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { GetLabel("lblStatus").Text = "在字典中未找到密码"; GetTextBox("txtCurrentPassword").Text = "未找到匹配的密码"; python } GetButton("btnStart").Enabled = true; GetButton("btnCancel").Enabled = false; } private void BtnCancel_Click(object sender, EventArgs e) { if (worker.IsBusy) { worker.CancelAsync(); GetButton("btnCancel").Enabled = false; GetLabel("lblStatus").Text = "正在取消操作..."; } } private void LinkLegal_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { MessageBox.Show("本工具仅供教育目的使用\n\n" + "仅限您合法拥有的文件使用\n\n" + "未经授权访问他人文件是违法行为\n\n" + "使用本工具即表示您同意承担所有责任", "法律和道德声明", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void ResetUI() { GetButton("btnStart").Enabled = true; GetButton("btnCancel").Enabled = false; } // Helper methods to get controls by name private TextBox GetTextBox(string name) => this.Controls.Find(name, true).FirstOrDefault() as TextBox; private Label GetLabel(string name) => this.Controls.Find(name, true).FirstOrDefault() as Label; private Button GetButton(string name) => this.Controls.Find(name, true).FirstOrDefault() as Button; private ProgressBar GetProgressBar() => this.Controls.Find("progressBar", true).FirstOrDefault() as ProgressBar; } }
以上就是基于C#实现rar文件密码破解工具的详细内容,更多关于C#破解rar文件密码的资料请关注编程客栈(www.devze.com)其它相关文章!
精彩评论