2026-02-12 21:29:00 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
|
|
|
|
|
|
using Microsoft.Win32;
|
|
|
|
|
|
|
|
|
|
|
|
namespace ShrlAlgoStudio
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2026-02-17 22:17:23 +08:00
|
|
|
|
/// RevitFileCipherView.xaml 的交互逻辑
|
2026-02-12 21:29:00 +08:00
|
|
|
|
/// </summary>
|
2026-02-17 22:17:23 +08:00
|
|
|
|
public partial class RevitFileCipherView
|
2026-02-12 21:29:00 +08:00
|
|
|
|
{
|
2026-02-17 22:17:23 +08:00
|
|
|
|
public RevitFileCipherView()
|
2026-02-12 21:29:00 +08:00
|
|
|
|
{
|
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 定义要搜索的扩展名(注意:必须带点,且通常小写,因为 Windows 文件系统不区分大小写)
|
|
|
|
|
|
|
|
|
|
|
|
private static readonly string[] AllowedExtensions = { ".rvt", ".rfa", ".rft", ".rte" };
|
|
|
|
|
|
private void DecryptButton_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var openFileDialog = new OpenFileDialog();
|
|
|
|
|
|
if (openFileDialog.ShowDialog() == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
var filePath = openFileDialog.FileName;
|
|
|
|
|
|
string ext = Path.GetExtension(filePath).ToLowerInvariant();
|
|
|
|
|
|
|
|
|
|
|
|
if (AllowedExtensions.Contains(ext))
|
|
|
|
|
|
{
|
|
|
|
|
|
Decrypt(filePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void DecryptFolderButton_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dialog = new VistaFolderBrowserDialog();
|
|
|
|
|
|
if (!dialog.ShowDialog()) return;
|
|
|
|
|
|
var folderPath = dialog.SelectedPath;
|
|
|
|
|
|
var directoryPath = new DirectoryInfo(folderPath);
|
|
|
|
|
|
// 定义要搜索的扩展名(注意:必须带点,且通常小写,因为 Windows 文件系统不区分大小写)
|
|
|
|
|
|
|
|
|
|
|
|
var files = directoryPath
|
|
|
|
|
|
.GetFiles("*", SearchOption.AllDirectories)
|
|
|
|
|
|
.Where(file => AllowedExtensions.Contains(file.Extension.ToLowerInvariant()))
|
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
foreach (var filePath in files)
|
|
|
|
|
|
{
|
|
|
|
|
|
Decrypt(filePath.FullName);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
private void EncryptButton_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var openFileDialog = new OpenFileDialog();
|
|
|
|
|
|
if (openFileDialog.ShowDialog() == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
var filePath = openFileDialog.FileName;
|
|
|
|
|
|
string ext = Path.GetExtension(filePath).ToLowerInvariant();
|
|
|
|
|
|
|
|
|
|
|
|
if (AllowedExtensions.Contains(ext))
|
|
|
|
|
|
{
|
|
|
|
|
|
Encrypt(filePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void EncryptFolderButton_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dialog = new VistaFolderBrowserDialog();
|
|
|
|
|
|
if (!dialog.ShowDialog()) return;
|
|
|
|
|
|
var folderPath = dialog.SelectedPath;
|
|
|
|
|
|
|
|
|
|
|
|
var directoryPath = new DirectoryInfo(folderPath);
|
|
|
|
|
|
|
|
|
|
|
|
var files = directoryPath
|
|
|
|
|
|
.GetFiles("*", SearchOption.AllDirectories)
|
|
|
|
|
|
.Where(file => AllowedExtensions.Contains(file.Extension.ToLowerInvariant()))
|
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
foreach (var filePath in files)
|
|
|
|
|
|
{
|
|
|
|
|
|
Encrypt(filePath.FullName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private bool IsEncrypted(string filePath, string tag = "VmVyc2lvbiAxLjAgU1pNZWRpRGF0YQ==")
|
|
|
|
|
|
{
|
|
|
|
|
|
// 关键:用写入时相同的编码(通常 UTF-8 或 ASCII)
|
|
|
|
|
|
var tagBytes = Encoding.UTF8.GetBytes(tag); // 或 Encoding.ASCII
|
|
|
|
|
|
|
|
|
|
|
|
var data = File.ReadAllBytes(filePath);
|
|
|
|
|
|
// 检查开头和结尾是否匹配
|
|
|
|
|
|
var startMatch = data.Length >= tagBytes.Length &&
|
|
|
|
|
|
ArrayEquals(data, 0, tagBytes, 0, tagBytes.Length);
|
|
|
|
|
|
var endMatch = data.Length >= tagBytes.Length * 2 &&
|
|
|
|
|
|
ArrayEquals(data, data.Length - tagBytes.Length, tagBytes, 0, tagBytes.Length);
|
|
|
|
|
|
return startMatch && endMatch;
|
|
|
|
|
|
}
|
|
|
|
|
|
private static void Decrypt(string filePath, string tag = "VmVyc2lvbiAxLjAgU1pNZWRpRGF0YQ==")
|
|
|
|
|
|
{
|
|
|
|
|
|
// 关键:用写入时相同的编码(通常 UTF-8 或 ASCII)
|
|
|
|
|
|
var tagBytes = Encoding.UTF8.GetBytes(tag); // 或 Encoding.ASCII
|
|
|
|
|
|
|
|
|
|
|
|
var data = File.ReadAllBytes(filePath);
|
|
|
|
|
|
|
|
|
|
|
|
// 检查开头和结尾是否匹配
|
|
|
|
|
|
var startMatch = data.Length >= tagBytes.Length &&
|
|
|
|
|
|
ArrayEquals(data, 0, tagBytes, 0, tagBytes.Length);
|
|
|
|
|
|
var endMatch = data.Length >= tagBytes.Length * 2 &&
|
|
|
|
|
|
ArrayEquals(data, data.Length - tagBytes.Length, tagBytes, 0, tagBytes.Length);
|
|
|
|
|
|
|
|
|
|
|
|
if (startMatch && endMatch)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 提取中间部分:去掉开头和结尾的 tag
|
|
|
|
|
|
var start = tagBytes.Length;
|
|
|
|
|
|
var length = data.Length - 2 * tagBytes.Length;
|
|
|
|
|
|
var original = new byte[length];
|
|
|
|
|
|
Array.Copy(data, start, original, 0, length);
|
|
|
|
|
|
|
|
|
|
|
|
File.WriteAllBytes(filePath, original);
|
|
|
|
|
|
Console.WriteLine("✅ 文件已成功还原!");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine("❌ 文件开头或结尾不匹配标记字符串。");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private static void Encrypt(string markedRvtPath, string tag = "VmVyc2lvbiAxLjAgU1pNZWRpRGF0YQ==")
|
|
|
|
|
|
{
|
|
|
|
|
|
// 选择编码:通常用 UTF-8 或 ASCII(必须与后续读取时一致)
|
|
|
|
|
|
var encoding = Encoding.UTF8; // 或 Encoding.ASCII
|
|
|
|
|
|
|
|
|
|
|
|
var tagBytes = encoding.GetBytes(tag);
|
|
|
|
|
|
var originalData = File.ReadAllBytes(markedRvtPath);
|
|
|
|
|
|
|
|
|
|
|
|
// 构造新文件内容:[tag] + [原始内容] + [tag]
|
|
|
|
|
|
var newLength = (long)tagBytes.Length * 2 + originalData.Length;
|
|
|
|
|
|
var markedData = new byte[newLength];
|
|
|
|
|
|
|
|
|
|
|
|
// 写入头部 tag
|
|
|
|
|
|
//Array.Copy(tagBytes, 0, markedData, 0, tagBytes.Length);
|
|
|
|
|
|
// 写入原始内容
|
|
|
|
|
|
Array.Copy(originalData, 0, markedData, tagBytes.Length, originalData.Length);
|
|
|
|
|
|
// 写入尾部 tag
|
|
|
|
|
|
Array.Copy(tagBytes, 0, markedData, tagBytes.Length + originalData.Length, tagBytes.Length);
|
|
|
|
|
|
|
|
|
|
|
|
// 保存新文件
|
|
|
|
|
|
File.WriteAllBytes(markedRvtPath, markedData);
|
|
|
|
|
|
Console.WriteLine("✅ 文件已成功加密!");
|
|
|
|
|
|
}
|
|
|
|
|
|
static bool ArrayEquals(byte[] a, int aStart, byte[] b, int bStart, int length)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var i = 0; i < length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (a[aStart + i] != b[bStart + i])
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void IsDecrypt_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var openFileDialog = new OpenFileDialog();
|
|
|
|
|
|
if (openFileDialog.ShowDialog() == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
var filePath = openFileDialog.FileName;
|
|
|
|
|
|
string ext = Path.GetExtension(filePath).ToLowerInvariant();
|
|
|
|
|
|
|
|
|
|
|
|
if (AllowedExtensions.Contains(ext))
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show($"是否加密:{IsEncrypted(filePath)}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|