💡 Ví dụ hoạt động đầy đủ có sẵn trên GitHub:
compare-encrypted-pdf-and-word-documents-dotnet

Cách Cũ Đầy Đau Đớn

Hai phiên bản của một thỏa thuận cung ứng xuất hiện trong hộp thư của bạn. Cả hai đều được bảo vệ bằng mật khẩu, mỗi tài liệu có một mật khẩu khác nhau, và ai đó cần một bản sao đã được đánh dấu các thay đổi. Thư viện so sánh bạn đang dùng yêu cầu đầu vào dạng văn bản thuần, vì vậy quy trình phải thêm một bước: giải mã cả hai tệp vào thư mục tạm, so sánh các bản sao văn bản thuần, rồi nhớ xóa chúng. Thư mục tạm này giờ trở thành mắt xích yếu nhất trong một quy trình làm việc tồn tại riêng vì các tài liệu nhạy cảm.

Có một phiên bản thứ hai của cùng vấn đề mà dễ bị bỏ qua. Một số nhóm bỏ qua thư mục tạm và giải mã vào bộ nhớ thay vì đĩa, điều này giải quyết vấn đề dọn dẹp nhưng không giải quyết vấn đề định dạng: API giải mã khác nhau tùy theo định dạng, vì vậy hỗ trợ bảng tính được mã hoá sau các PDF được mã hoá đồng nghĩa với việc phải tích hợp một lần nữa thay vì chỉ thêm một dòng mã.

Chi phí không chủ yếu nằm ở lời gọi giải mã – mà là ở mọi thứ xung quanh nó. Các bản sao văn bản thuần phải được ghi ở đâu đó, phải được dọn dẹp trên mọi đường đi thoát, kể cả các trường hợp lỗi, và phải được giữ ra khỏi sao lưu và dump khi gặp sự cố. Một diff được tạo theo cách đó cũng mặc định không được bảo vệ, vì vậy đầu ra của hai đầu vào được mã hoá trở thành tệp duy nhất trong chuỗi mà bất kỳ ai cũng có thể mở.

Chi phí thực sự của vòng lặp giải mã: một thư mục tạm chứa các bản sao văn bản thuần của các tài liệu đã được mã hoá vì một lý do, với việc dọn dẹp phải đúng trên mọi đường lỗi.

Có Một Cách Tốt Hơn

So sánh tài liệu được bảo vệ bằng mật khẩu là một khả năng của GroupDocs.Comparison cho .NET, cho phép mở các tệp PDF, DOCX, XLSX và PPTX đã được mã hoá ngay tại chỗ và quyết định mật khẩu nào sẽ bảo vệ kết quả so sánh. Không cần bước giải mã, không có trung gian dạng văn bản thuần: mật khẩu đi cùng tài liệu vào trong quá trình so sánh, như một thuộc tính trên LoadOptions.

Trước khi bắt đầu, bạn sẽ cần:

  • .NET 8.0 SDK hoặc mới hơn
  • GroupDocs.Comparison 26.9.0 (giấy phép tạm thời)
  • Hai tài liệu đã được mã hoá cùng định dạng, và mật khẩu của chúng

Cài đặt bằng một lệnh:

dotnet add package GroupDocs.Comparison

Cách Mới: Tài Liệu Được Mã Hoá Trực Tiếp Vào Bộ So Sánh

Ví dụ dưới đây so sánh hai PDF đã được mã hoá – nguồn mở bằng 1234, đích mở bằng 4321 – và ghi một tệp kết quả duy nhất với các thay đổi được hợp nhất nội tuyến. Mật khẩu cố ý khác nhau, vì đó là nơi lỗi đầu tiên ẩn náu.

Bước 1 - Đưa mỗi tài liệu một LoadOptions riêng

Một Comparer chứa một nguồn và bất kỳ số lượng đích nào, và mỗi tài liệu mang bảo vệ riêng của nó. Mật khẩu của nguồn được truyền vào hàm khởi tạo; mật khẩu của mỗi đích được truyền vào lời gọi Add riêng của nó.

// One LoadOptions per document - the constructor's options unlock the
// source only, and never reach the targets.
using var comparer = new Comparer("source.pdf",
    new LoadOptions { Password = "1234" });
comparer.Add("target.pdf", new LoadOptions { Password = "4321" });

Đây là chi tiết khiến nhiều người gặp rắc rối. Việc truyền một LoadOptions duy nhất vào hàm khởi tạo và mong rằng nó sẽ bao phủ các đích là cách sai phổ biến nhất, và vì thời điểm lỗi xảy ra, nó không thông báo ở nơi bạn sẽ tìm kiếm.

Bước 2 - Quyết Định Điều Gì Bảo Vệ Kết Quả

CompareOptions.PasswordSaveOption chọn cách bảo vệ đầu ra: None, Source, Target, hoặc User. Mặc định là None, khiến hai đầu vào được mã hoá biến thành một kết quả không được bảo vệ.

// Inline markup, and the result reuses the source document's password.
var options = new PdfCompareOptions
{
    DisplayMode = PdfCompareOptions.ComparisonDisplayMode.Inline,
    PasswordSaveOption = PasswordSaveOption.Source
};

comparer.Compare("Result/1-pdf-inline.pdf", options);

Các điểm quan trọng:

  • PasswordSaveOption: Source tái sử dụng mật khẩu của tài liệu nguồn cho đầu ra. Chọn User cùng với SaveOptions.Password để cấp một mật khẩu mới.
  • ComparisonDisplayMode: nằm trong PdfCompareOptions, cũng cung cấp SideBySide và Interleaved. WordCompareOptions khai báo enum cùng tên nhưng giá trị khác, vì vậy không thể dùng tên thuần – phải chỉ định đầy đủ.

Bước 3 - Bảo Vệ Đầu Ra Bằng Mật Khẩu Riêng

Khi diff được gửi tới những người xem không nên biết bất kỳ mật khẩu gốc nào, PasswordSaveOption.User lấy giá trị từ SaveOptions.Password thay vì tái sử dụng mật khẩu đầu vào.

var compareOptions = new PdfCompareOptions
{
    DisplayMode = PdfCompareOptions.ComparisonDisplayMode.Inline,
    PasswordSaveOption = PasswordSaveOption.User
};
var saveOptions = new SaveOptions { Password = "5678" };

comparer.Compare("Result/4-own-password.pdf", saveOptions, compareOptions);

Cả hai đối tượng đều được truyền vào overload Compare ba tham số. Đặt SaveOptions.Password một mình không thay đổi gì – giá trị enum mới kích hoạt việc lưu mật khẩu phía đầu ra. Kết quả của lời gọi này mở bằng 5678 và từ chối 1234.

Tại sao khối try/catch quanh Comparer không bắt được mật khẩu sai?

Bởi vì hàm khởi tạo không bao giờ mở tài liệu. Nó chỉ ghi lại đường dẫn, và Add cũng vậy. Cả hai tài liệu đều được đọc khi Compare chạy, và ở đó PasswordProtectedFileException với thông báo Password is missing được ném ra. Một mật khẩu sai hành xử tương tự: nó được chấp nhận im lặng ở thời điểm khởi tạo, rồi bị từ chối sau này tại Compare.

Vì vậy hãy bảo vệ lời gọi so sánh, không phải hàm khởi tạo. Tôi đã phát hiện ra điều này một cách chậm rãi, bao bọc việc khởi tạo trong một try và quan sát một tệp được mã hoá đi thẳng qua mà không lỗi cho đến ba dòng sau khi thất bại. Kho lưu trữ in ra mỗi giai đoạn, khiến thứ tự rõ ràng ngay lần đọc đầu tiên:

using var comparer = new Comparer("source.pdf");   // succeeds
comparer.Add("target.pdf");                        // succeeds
comparer.Compare("Result/unreachable.pdf");        // throws here

So Sánh Bên Cạnh: Trước và Sau

Trước (giải mã trước) Sau (GroupDocs.Comparison)
Các bước quy trình Giải mã cả hai, so sánh, xóa bản sao tạm So sánh
Văn bản thuần trên đĩa Hai bản sao, dọn dẹp trên mọi đường lỗi Không có
Bảo vệ kết quả Một bước mã hoá lại riêng Một giá trị PasswordSaveOption
Phạm vi định dạng Công cụ giải mã riêng theo định dạng Một LoadOptions.Password cho PDF, DOCX, XLSX, PPTX
Mã cần thiết Trợ giúp giải mã cộng với so sánh 4 dòng

Các tính năng so sánh không thay đổi khi đầu vào được mã hoá. Các chế độ hiển thị, trang tóm tắt và phát hiện kiểu đều hoạt động giống như với tệp văn bản thuần, vì bảo vệ được xử lý hoàn toàn ở lớp tải.

Lớp này chính là lý do khiến phạm vi định dạng trở nên rẻ tiền. LoadOptions.Password chỉ là một thuộc tính string đơn giản, và cùng một thuộc tính này mở khóa PDF, DOCX, XLSX và PPTX – mã tải trong ví dụ Word phía dưới là ký tự‑đối‑ký tự giống như ví dụ PDF. Chỉ có lớp tùy chọn thay đổi, và chỉ vì mỗi định dạng cung cấp các lựa chọn render khác nhau. Thêm hỗ trợ bảng tính đã mã hoá vào mã đã so sánh PDF đã mã hoá không tốn gì trong đường tải.

Ví Dụ Thực Tế: Đánh Dấu Hợp Đồng Giữa Các Văn Phòng Luật

Một đội pháp lý nhận mỗi phiên bản của một thỏa thuận đã được mã hoá, với mật khẩu được thay đổi theo mỗi lần trao đổi để một mật khẩu bị rò rỉ không làm lộ toàn bộ lịch sử. Đối tác xem xét cần một tài liệu đã được đánh dấu cho mỗi vòng, và theo quy định lưu trữ, bản sao đã đánh dấu không được để không bảo vệ trên một chia sẻ tệp.

Hai cài đặt đáp ứng nhu cầu này. Mỗi tài liệu được mở bằng LoadOptions riêng, vì vậy việc thay đổi mật khẩu không cần xử lý đặc biệt, và PasswordSaveOption.User cung cấp cho mỗi diff đã phân phối một mật khẩu riêng – một mật khẩu mở khóa so sánh và không gì hơn.

// Word revisions, so the reviewing partner can accept or reject each edit.
var options = new WordCompareOptions
{
    DisplayMode = WordCompareOptions.ComparisonDisplayMode.Revisions,
    PasswordSaveOption = PasswordSaveOption.Source
};

using var comparer = new Comparer("round3.docx",
    new LoadOptions { Password = "1234" });
comparer.Add("round4.docx", new LoadOptions { Password = "4321" });
comparer.Compare("Result/redline.docx", options);

Bạn Còn Có Thể Làm Gì Với GroupDocs.Comparison?

  • So sánh hơn hai tài liệu được bảo vệ: thêm nhiều mục tiêu đã mã hoá vào một lần so sánh, cho định dạng Word và bản trình bày.
  • Tạo bản sửa đổi Word gốc: WordCompareOptions.ComparisonDisplayMode.Revisions ghi các thay đổi mà người xem có thể chấp nhận hoặc từ chối trực tiếp trong Word.
  • Kiểm soát việc tải tài nguyên bên ngoài: chặn hoặc cho phép danh sách trắng các tham chiếu từ xa mà tài liệu mang theo, một biện pháp bảo vệ khác của LoadOptions.
  • Tạo trang tóm tắt: GenerateSummaryPage thêm tổng quan các thay đổi vào tài liệu kết quả.

Kết Luận

Vòng lặp giải mã không bao giờ là vấn đề của việc so sánh – mà là của một thư viện không thể đọc những gì bạn có. Đặt LoadOptions.Password cho mỗi tài liệu loại bỏ thư mục tạm, các đường dọn dẹp, và diff không được bảo vệ ở cuối chuỗi. Ba quyết định là tất cả những gì còn lại: một mật khẩu cho mỗi tài liệu, một PasswordSaveOption rõ ràng thay vì mặc định None, và xử lý lỗi quanh Compare nơi thất bại thực sự xảy ra.

Sẵn sàng tự động hoá quy trình tài liệu của bạn?

Tài Nguyên Bổ Sung