💡 Contoh kerja penuh tersedia di GitHub:
compare-encrypted-pdf-and-word-documents-dotnet

Cara Lama Sangat Menyakitkan

Dua revisi perjanjian pasokan masuk ke kotak masuk Anda. Kedua dokumen dilindungi kata sandi, masing‑masing dengan kata sandi yang berbeda, dan seseorang membutuhkan salinan yang ditandai menunjukkan apa yang berubah. Perpustakaan perbandingan yang Anda miliki mengharapkan masukan teks biasa, jadi alur kerja menambah satu langkah: dekripsi kedua file ke folder sementara, bandingkan salinan teks biasa, lalu ingat untuk menghapusnya. Folder sementara itu kini menjadi titik terlemah dalam alur kerja yang ada khusus karena dokumen sensitif.

Ada versi kedua dari masalah yang sama yang lebih mudah terlewat. Beberapa tim melewatkan folder sementara dan mendekripsi ke memori saja, yang menyelesaikan pertanyaan pembersihan tetapi tidak pertanyaan format: API dekripsi berbeda per format, jadi mendukung spreadsheet terenkripsi setelah PDF terenkripsi berarti integrasi kedua bukan baris kode kedua.

Biayanya bukan pada pemanggilan dekripsi – melainkan pada segala sesuatu di sekitarnya. Salinan teks biasa harus ditulis di suatu tempat, dibersihkan pada setiap jalur keluar termasuk yang gagal, dan dijauhkan dari cadangan serta dump crash. Diff yang dihasilkan dengan cara itu juga muncul tidak terlindungi secara default, sehingga output dari dua masukan terenkripsi menjadi satu file di rantai yang siapa pun dapat membuka.

Biaya nyata dari penyimpangan dekripsi: direktori sementara yang menyimpan salinan teks biasa dokumen yang dienkripsi karena alasan, dengan pembersihan yang harus benar pada setiap jalur error.

Ada Cara yang Lebih Baik

Perbandingan yang dilindungi kata sandi adalah kemampuan GroupDocs.Comparison untuk .NET yang membuka file PDF, DOCX, XLSX, dan PPTX terenkripsi di tempat dan memutuskan kata sandi apa yang melindungi hasil perbandingan. Tanpa langkah dekripsi, tanpa perantara teks biasa: kata sandi ikut bersama dokumen ke dalam perbandingan itu sendiri, sebagai properti pada LoadOptions.

Sebelum kita mulai, Anda memerlukan:

  • .NET 8.0 SDK atau yang lebih baru
  • GroupDocs.Comparison 26.9.0 (temporary licence)
  • Dua dokumen terenkripsi dengan format yang sama, dan kata sandi mereka

Pasang dengan satu perintah:

dotnet add package GroupDocs.Comparison

Cara Baru: Dokumen Terenkripsi Langsung ke Comparer

Contoh di bawah membandingkan dua PDF terenkripsi – sumber dibuka dengan 1234, target dengan 4321 – dan menulis satu file hasil dengan perubahan yang digabungkan secara inline. Kata sandi sengaja berbeda, karena di situlah kesalahan pertama tersembunyi.

Langkah 1 - Beri setiap dokumen LoadOptions masing‑masing

Comparer memegang satu sumber dan sejumlah target, dan setiap dokumen membawa perlindungan sendiri. Kata sandi sumber diberikan ke konstruktor; kata sandi setiap target diberikan ke pemanggilan Add masing‑masing.

// 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" });

Inilah detail yang membuat orang kebingungan. Mengirim satu LoadOptions ke konstruktor dan mengharapkan itu mencakup target adalah cara paling umum yang salah, dan karena cara kegagalannya terjadinya, ia tidak mengumumkan dirinya di tempat yang Anda cari.

Langkah 2 - Tentukan apa yang melindungi hasil

CompareOptions.PasswordSaveOption memilih perlindungan output: None, Source, Target, atau User. Defaultnya adalah None, yang diam‑diam mengubah dua masukan terenkripsi menjadi satu hasil yang tidak terlindungi.

// 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);

Poin penting:

  • PasswordSaveOption: Source menggunakan kembali kata sandi sumber pada output. Pilih User dengan SaveOptions.Password untuk memberikan kata sandi baru.
  • ComparisonDisplayMode: berada di dalam PdfCompareOptions, yang juga menawarkan SideBySide dan Interleaved. WordCompareOptions mendeklarasikan enum dengan nama yang sama tetapi nilai berbeda, sehingga nama saja tidak akan terkompilasi – beri kualifikasi.

Langkah 3 - Lindungi output dengan kata sandi sendiri

Ketika diff dikirim ke peninjau yang tidak seharusnya mengetahui kata sandi asli, PasswordSaveOption.User mengambil nilai dari SaveOptions.Password alih-alih menggunakan kembali kata sandi masukan.

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);

Kedua objek dikirim ke overload Compare dengan tiga argumen. Menetapkan SaveOptions.Password saja tidak mengubah apa‑apa – nilai enum yang mengaktifkan kata sandi sisi penyimpanan. Hasil dari pemanggilan ini terbuka dengan 5678 dan menolak 1234.

Mengapa try/catch di sekitar Comparer tidak menangkap kata sandi yang salah?

Karena konstruktor tidak pernah membuka dokumen. Ia hanya mencatat jalur, begitu juga Add. Kedua dokumen dibaca ketika Compare dijalankan, dan di situlah PasswordProtectedFileException dengan pesan Password is missing dilempar. Kata sandi yang salah berperilaku identik: diterima secara diam pada saat konstruksi, lalu ditolak kemudian pada Compare.

Jadi lindungi pemanggilan perbandingan, bukan konstruktor. Saya menemukan ini dengan cara lambat, membungkus konstruksi dalam try dan melihat file terenkripsi melaju lurus sebelum gagal tiga baris kemudian. Repository mencetak setiap tahap, yang membuat urutan jelas pada bacaan pertama:

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

Sisi‑Sisi: Sebelum vs. Sesudah

Sebelum (decrypt dulu) Sesudah (GroupDocs.Comparison)
Langkah pipeline Decrypt kedua file, bandingkan, hapus salinan sementara Bandingkan
Teks biasa di disk Dua salinan, bersihkan pada setiap jalur error Tidak ada
Perlindungan hasil Langkah re‑enkripsi terpisah Satu nilai PasswordSaveOption
Cakupan format Alat dekripsi per format Satu LoadOptions.Password untuk PDF, DOCX, XLSX, PPTX
Kode yang diperlukan Helper dekripsi plus perbandingan 4 baris

Fitur perbandingan tidak berubah pada masukan terenkripsi. Mode tampilan, halaman ringkasan, dan deteksi gaya berperilaku persis seperti pada file teks biasa, karena perlindungan ditangani sepenuhnya di lapisan pemuatan.

Lapisan itu yang membuat cakupan format menjadi murah. LoadOptions.Password adalah properti string biasa, dan properti yang sama membuka PDF, DOCX, XLSX, dan PPTX – kode pemuatan pada contoh Word di bawah ini persis karakter‑per‑karakter dengan contoh PDF. Hanya kelas opsi yang berubah, dan hanya karena tiap format menawarkan pilihan rendering yang berbeda. Menambahkan dukungan spreadsheet terenkripsi ke kode yang sudah membandingkan PDF terenkripsi tidak menambah apa‑apa pada jalur pemuatan.

Contoh Dunia Nyata: Redlining Kontrak Antara Firma Hukum

Tim hukum menerima setiap revisi perjanjian terenkripsi, dengan kata sandi diputar per pertukaran sehingga kata sandi yang bocor tidak mengungkap seluruh riwayat. Partner peninjau membutuhkan satu dokumen ber‑markup per putaran, dan menurut aturan retensi salinan ber‑markup tidak boleh berada tidak terlindungi di file share.

Dua pengaturan menutupi kebutuhan ini. Setiap dokumen dibuka dengan LoadOptions masing‑masing, sehingga pergantian kata sandi tidak memerlukan penanganan khusus, dan PasswordSaveOption.User memberi setiap diff yang didistribusikan kata sandi sendiri – satu yang membuka perbandingan dan tidak lebih.

// 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);

Apa Lagi yang Bisa Anda Lakukan dengan GroupDocs.Comparison?

  • Bandingkan lebih dari dua dokumen terlindungi: tambahkan beberapa target terenkripsi ke satu perbandingan, untuk format Word dan presentasi.
  • Hasilkan revisi Word native: WordCompareOptions.ComparisonDisplayMode.Revisions menulis perubahan yang dapat diterima atau ditolak peninjau langsung di Word.
  • Kendalikan pemuatan sumber eksternal: blokir atau beri whitelist referensi remote yang dibawa dokumen, perlindungan LoadOptions lainnya.
  • Buat halaman ringkasan: GenerateSummaryPage menambahkan ikhtisar perubahan ke dokumen hasil.

Kesimpulan

Penyimpangan dekripsi sebenarnya bukan tentang perbandingan – melainkan tentang perpustakaan yang tidak dapat membaca apa yang Anda miliki. Menetapkan LoadOptions.Password per dokumen menghilangkan folder sementara, jalur pembersihan, dan diff tidak terlindungi di akhir rantai. Tiga keputusan saja yang tersisa: kata sandi per dokumen, PasswordSaveOption eksplisit alih‑alih default None, dan penanganan error di sekitar Compare tempat kegagalan benar‑benar terjadi.

Siap mengotomatisasi alur kerja dokumen Anda?

Sumber Daya Tambahan