Parašas ant PDF nedraudžia vėlesnių pakeitimų. Jis užfiksuoja baitų intervalą, o prieauginis atnaujinimas po jo prideda naujų baitų, todėl parašas lieka matematiškai teisėtas, kol dokumentas įgyja naujo turinio. Ar tas turinys priimtinas — politikos klausimas, ir DocMDP yra vieta, kur autorius tą politiką deklaruoja: jokių pakeitimų, tik formų pildymas ir pasirašymas, arba tai plus anotacijos. Jo vykdymas reiškia klasifikavimą, kas iš tikrųjų pasikeitė, ir būtent tai daro AnalyzeModifications. Nukreipkite ją į ankstesnę reviziją, paskui skaitykite GetModificationLevel dėl bendro verdikto ir atskirų radinių prieigos metodus dėl kiekvieno skirtumo lygio, objekto numerio ir aprašo
Tai turint, DocMDP vykdymas susiskleidžia į vieną palyginimą: ar apskaičiuotas lygis neviršija politikos leidžiamo lygio
Kodėl tikimasi, kad pasirašytas PDF pasikeis
Trys teisėti atvejai, ir jie dengia daugumą to, ką matysite. Antrasis pasirašantysis prideda savo parašą. Gavėjas pildo formų laukus, kuriuos autorius paliko atvirus. Ir pridedama ilgalaikio tikrinimo medžiaga: OCSP atsakai ir CRL įrašomi į dokumento saugos saugyklą, kad parašas liktų patikrinamas, kai atsakiklių jau nebėra. Tas paskutinis ne tik leistinas — būtent to sąmoningai imasi gerai tvarkomas archyvas su pasirašytais dokumentais
Taigi „failas paaugo po pasirašymo“ informacijos neša nė kiek. Klausimas visada yra, kas pridėta, o atsakymas turi ateiti iš dokumento būsenų palyginimo, o ne iš baitų stebėjimo. Pačios priedų mechanikos aprašytos prieauginio atnaujinimo straipsnyje
Klasifikuokite pagal objekto formą, o ne pagal kelią, jį pagaminusį
Klasifikatorius žiūri, kas objektas yra po pakeitimo, o ne kuri bibliotekos funkcija jį sukūrė. Tai sąmoninga, nes analizė vykdoma prieš kitos programinės įrangos pagamintus failus, kur nėra jokio galimo patikrinti iškvietimų kelio
Atpažįstamos keturios formos. Dokumentų saugos saugykla ir su tikrinimu susiję informacijos žodynai, kryžminių nuorodų srauto objektai, katalogo metadata įrašas ir parašų žodynai su baitų intervalu yra ilgalaikio archyvo medžiaga. Objektas, nešantis ir lauko tipą, ir lauko reikšmę, yra formų pildymas. Objektas, kurio tipas yra annotation arba kurio potipis vienas iš ISO 32000-2 168 lentelėje išvardytų, yra anotacijos pakeitimas. Visa kita — neklasifikuota
Pašalinimai traktuojami griežčiau nei pridėjimai. Pašalintas objektas į baltąjį sąrašą patenka tik tada, kai senosios pusės objektas pats buvo archyvo medžiaga — tai dengia įprastą atvejį, kai saugos saugyklą pakeičia naujesnė. Kiekvienas kitas pašalinimas neklasifikuotas, nes turinio trynimas iš pasirašyto dokumento nėra tai, ką leistų koks nors teisės lygis. Dokumentų lygio skirtumai griežtesni dar labiau: puslapių skaičiaus pokytis keliauja tiesiai į neklasifikuotuosius be atskirų objektų apžiūrėjimo, nes joks DocMDP lygis neleidžia pridėti ar šalinti puslapių
Baltasis sąrašas klysta atsisakydamas
Tai projektavimo taisyklė, valdanti kiekvieną ribinį sprendimą. Pakeitimas, neteisingai klasifikuotas kaip leistinas, yra parašas, patvirtinantis turinį, kurio autorius niekada nesuteikė teisės. Pakeitimas, neteisingai klasifikuotas kaip neklasifikuotas, yra dokumentas, pažymėtas ir peržiūrimas žmogaus. Šios dvi klaidos nėra simetriškos, todėl baltasis sąrašas lieka siauras, o neatpažintos formos krenta į neklasifikuotąsias, vietoj to, kad būtų spėjamos
Turi tai praktinę pasekmę, vertą numatyti iš anksto: neįprastų gamintojų failai kartais praneša neklasifikuotus pakeitimus, kurie, apžiūrėjus, yra nekalti. Teisingas atsakas — žvilgtelti į radinio detalę ir objekto numerį, o ne platinti baltąjį sąrašą, nes baltasis sąrašas, išaugęs nutylėti atskirus pranešimus, nustoja būti saugos kontrole
uses
PDFlibrary, PDFlibCompare;
var
Pdf: TPDFlib;
I, Level: Integer;
begin
Pdf := TPDFlib.Create(nil);
try
Pdf.LoadFromFile('contract-countersigned.pdf', '');
if Pdf.AnalyzeModifications('contract-as-signed.pdf', '') < 0 then
raise Exception.Create('the earlier revision could not be loaded');
// TPLModificationLevel tvarka mlNone, mlLTAUpdates, mlFormFilling,
// mlAnnotations, mlUnclassified; getteris grąžina jo eilės numerį
Level := Pdf.GetModificationLevel;
// DocMDP vykdymas dabar yra vienas palyginimas su politika
if Level > Ord(mlFormFilling) then
for I := 0 to Pdf.GetModificationFindingCount - 1 do
Report.Add(Format('object %d, level %d: %s',
[Pdf.GetModificationFindingObjNum(I),
Pdf.GetModificationFindingLevel(I),
Pdf.GetModificationFindingDetail(I)]));
finally
Pdf.Free;
end;
end;
Bendras lygis yra maksimumas per visus radinius, ir tai vienintelis ginamas susivedimas: dokumentas su devyniasdešimt devyniais archyvo pridėjimais ir vienu neklasifikuotu pakeitimu yra neklasifikuotas pakeitimas
Apatinis sluoksnis: pirštų atspaudai, o ne kriptografinės maišos
Palyginimo variklis, kurį atveria CompareWith ir ant kurio pastatyta pakeitimų analizė, atpažįsta objektus pagal jų normalizuoto kūno atspaudą (fingerprint), naudodama nekriptografinę 64 bitų maišą, o ne SHA-256. Tai apsvarstytas pasirinkimas. Struktūriniam palyginimui reikia determinizmo: tas pats objekto kūnas toje pačioje sekoje turi visada duoti tą patį atspaudą. Atsparumo susidūrimams nereikia, nes užpuolikas, valdantis abi palyginimo puses, jau laimėjo kitais būdais, o mokėti už pilną kriptografinę maišą kiekvienam objektui milijono objektų dokumente yra reali kaina be jokios naudos
Dvi normalizavimo taisyklės svarbesnės nei maišos pasirinkimas. Netiesioginės nuorodos susisuka į vietos ženklą, vietoj išskleidimo į nurodytą turinį: išskleidimas nukopijuotų bendro objekto kūną kiekvienam nurodytojui, todėl vienas nedidelis bendro šriftų deskriptoriaus pakeitimas sugadintų kiekvieno jo pasiekiamo objekto atspaudą, o ataskaita būtų neskaitytina. Ir patys objektų numeriai neįtraukiami į atspaudą, nes perrašymas gali pernumeruoti objektus nesukeldamas jokių semantinių pokyčių
Sutapimas tada vyksta dviem etapais: pirmiausia suvienodinama pagal atspaudą, o likutis suporuojamas pagal objekto numerį, kad pakeitimai būtų atpažįstami kaip pakeitimai, o ne kaip pridėjimas plus pašalinimas. Visur pirmiausia pigūs patikrinimai: puslapių skaičiaus skirtumas pranešamas dar prieš bet kokį objektų apėjimą
Spąstai: dokumento palyginimas su savimi nebūtinai duoda identišką rezultatą
Natūralus pirmasis skirtumų variklio testas — palyginti failą su pačiu savimi ir teigti, kad rezultatas identiškas. Čia tas teiginys nesilaiko, ir priežastis instruktyvi. Viešasis įkėlimo kelias ir žemesnio lygio dokumento įkėlimo kelias dekodavimą sukonfigūruoja nevienodai, todėl tas pats failas, įkeltas dviem maršrutais, gali duoti atspaudus, kurie kai kuriems objektams skiriasi. Variklis ne kaltas; du įkėlimai iš tikrųjų pagamino skirtingas atminties būsenas
Vietoje to, kad versti abu kelius kartu, palyginimo semantika suformuluota siaurai: analizė lygina dabartinę dokumento būseną su ankstesne revizija ir praneša „identiška“ tik tada, kai abu atspaudų rinkiniai sutampa tiksliai. Tai klausimas, kurį vartotojai iš tikrųjų užduoda, ir jam nereikia, kad abu įkėlikliai būtų sukeičiami. Projektuojant palyginimo savybę, tai, ką reiškia „tas pats“, apibrėžti yra didesnė darbo dalis nei jo skaičiavimas
Kur tai naudoti
Dviejose vietose. Tikrinimo ataskaitoje, greta parašų patikros, kad peržiūrėtojas matytų ne tik tai, ar parašas kriptografiškai nepažeistas, bet ir kas su dokumentu įvyko vėliau; parašų pusę dengia PAdES pasirašymas ir tikrinimas. Ir priėmimo vartuose, kur iš išorės atkeliavęs dokumentas tikrinamas prieš jūsų išsiųstą kopiją, kad grąžinta sutartis su pridėta anotacija būtų traktuojama kitaip nei sutartis su pakeistu puslapiu
Viena išlyga dėl taikymo srities. Ši analizė sako, kas pasikeitė tarp dviejų tos pačios dokumentų linijos revizijų. Ji nesako, ar matomas turinys apgaulingas, ar formos lauko išvaizdos srautas atitinka jo reikšmę, ar už perdanga paslėptas tekstas dar tebėra turinio sraute. To reikia atskiro dėmesio, o turinio šalinimo pusę dengia tikrojo redagavimo (redaction) straipsnis. Analizės ir palyginimo įėjimo taškai dokumentuoti losLab PDF Developer Library produkto puslapyje