- Ticari bir PDF aracı olmadan PDF’nin metin içeriğini değiştirmek istiyorsanız, sıkıştırılmış akışları açmanız ve yazı tipine özgü kodlamayı izleyerek özgün metni ve yerine geçecek ifadeyi aynı şekilde değiştirmeniz gerekir
- Birçok PDF, gerçek belge metnini düz metin olarak değil sıkıştırılmış akışlar ve onaltılık gibi görünen dizeler halinde saklar;
qpdf --qdf --object-streams=disable ile bunu düzenlenebilir bir biçime daha yakın şekilde açabilirsiniz
- Metin blokları
BT, Tf, Td, Tj, ET gibi PDF komutlarından oluşur ve <002a004800570003003600480057> Tj gibi değerler basit Unicode kod noktaları olmayabilir
- Yazı tipine özgü ToUnicode eşlemesi içeren bir PDF ise
pdffonts ile emb ve uni alanlarının yes olup olmadığını kontrol edebilir, /ToUnicode 19 0 R gibi başvuruları takip ederek kodlama tablosunu bulabilirsiniz
- Bu yöntem, PDF standardının karmaşıklığı nedeniyle her dosyaya genellenmesi zor olsa da, bazı PDF’lerde özgün kodlamayı bularak find-and-replace ile metni değiştirmek mümkündür
Sıkıştırılmış PDF metin akışlarını açma
- PDF’yi bir metin düzenleyicide açtığınızda yapının bir kısmı okunabilir olsa da, gerçek belge metni görünmeyebilir
- Birçok PDF, metin verisini sıkıştırılmış biçimde saklar
- Sıkıştırılmış metin akışlarını incelemek için
qpdf kullanabilirsiniz
- Mac’te homebrew formula mevcut
- Linux dağıtımlarında da ilgili araçlar kullanılabilir
qpdf --qdf --object-streams=disable in.pdf out.pdf
- Düzenlemeden sonra akışları yeniden sıkıştırabilirsiniz
qpdf out-edited.pdf out-recompressed.pdf
- Yeniden sıkıştırma komutu hata verdi, ancak ortaya çıkan PDF Preview’da okunabildi
PDF komutlarının içinde metni bulma
- Sıkıştırma açıldıktan sonra bile metin, PDF komut bloklarının içinde kalır
- Temel bir metin bloğu şu şekilde görünür
BT
/Font_0 12 Tf
288 720 Td
<002a004800570003003600480057> Tj
ET
- PDF Reference’a göre bu blok sırasıyla şunları yapar
- Metin nesnesini başlatır
- Kullanılacak yazı tipini ve boyutunu ayarlar
- Sayfadaki başlangıç konumunu belirtir
- O konumda dizenin gliflerini çizer
- Metin nesnesini sonlandırır
Metnin neden doğrudan okunamadığı
<002a004800570003003600480057> gibi değerler onaltılık dizeler gibi görünse de, basit bir Unicode kod noktası listesi olmayabilir
- PDF, kodlamayı belirtmek için pek çok yöntem kullanır ve dosyanın içinde özel tanımlı kodlamalar barındırabilir
- Bu tür kodlamalar çoğunlukla Unicode kod noktalarına eşlenebilir
- Bu süreç, üzerinde çalıştığınız PDF’nin gömülü bir kodlama içerdiğini varsayar
- Diğer durumların nasıl ele alınacağı burada ele alınmıyor
Yazı tipi ve Unicode eşlemesini kontrol etme
- PDF’deki metin kodlaması belirli bir yazı tipiyle bağlantılıdır
pdffonts, PDF içindeki yazı tiplerini ve kodlamayla ilgili bilgileri gösterir
$ pdffonts sample.pdf
name type emb sub uni prob object ID
------------------------------------ ----------------- --- --- --- ---- ---------
CLDQZB+TrebuchetMS,Bold CID TrueType yes yes yes 9 0
YQBAIZ+TrebuchetMS CID TrueType yes yes yes 10 0
- Burada bakılması gereken alanlar şunlardır
emb: yazı tipinin PDF’ye gömülü olduğunu gösterir
uni: Unicode eşlemesi bulunduğunu gösterir
- Her iki değer de
yes ise, gereken eşlemeyi bulma ihtimaliniz vardır
/Font_0 gibi örnek yazı tipi tanımlayıcıları bazı durumlarda pdffonts çıktısındaki yazı tipi adıyla eşleşir
- İlgili örnekte
/Font_0, CLDQZB+TrebuchetMS,Bold yazı tipini gösteriyordu
ToUnicode eşleme tablosunu izleme
- Metinde kullanılan yazı tipinin tam adını bulduktan sonra, PDF içinde bu adı arayın
- Belirli bir noktada şu tür bir başvuru bulunabilir
/ToUnicode 19 0 R
- Bu değer, kodlama tablosu nesne kimliğini işaret eder
- Ardından
19 0 obj ifadesini arayarak ilgili tablo bulunabilir
Kodlama tablosunu kullanarak metin değiştirme
- Eşleme tablosunun kritik kısmı şu biçimde olabilir
38 beginbfrange^M
<0036><0036><0053>^M
<0057><0057><0074>^M
<0044><0044><0061>^M
<0048><0048><0065>^M
<0050><0050><006D>^M
...
- Bu örnek, özel tanımlı kodlama noktası aralıklarını Unicode noktalarına eşler
- Burada aralıklar tek karakter uzunluğundadır
0036, Unicode noktası 0053 ile eşlenir
- Tablo biçimi farklıysa ToUnicode mapping file tutorial belgesine bakabilirsiniz
- Otomatik dönüştürme için tablo Python ile bir sözlüğe çevrilip basit kodlama/kod çözme işlevleri yazılabilir
- Son değiştirme akışı şu şekildedir
- Değiştirilecek mevcut metnin özel kodlama değerini bulun
- Yerine gelecek metni aynı şekilde özel olarak kodlayın
- PDF içinde find-and-replace ile mevcut değeri değiştirin
1 yorum
Hacker News yorumları
PDF spesifikasyonu epey çetrefilli. Son zamanlarda en sevdiğim gereksiz bilgi, üst üste binen öğeleri işlerken Photoshop’taki tüm layer blend mode’larını desteklemesi
İkinci favorim de, sona eklenen içeriğin önceki içeriği değiştirebilmesi; bu yüzden tek bir dosyada temsil edilen farklı sürümlerin hepsinin adli incelemeye tabi tutulması gerekmesi
Bu aynı zamanda DRM’in beyhudeliğini gösteren bir örnek. Spesifikasyonda parola tabanlı şifreleme var; “owner” ve “user” parolaları ayrı ayrı belirlenebiliyor, ayrıca “yazdırma yasak”, “metin kopyalama yasak” gibi bit alanları da var. Ama belgeyi okumak için eninde sonunda şifresini çözmek gerektiğinden, “user” parolasıyla uyumsuz bir araçta şifreli PDF’yi açıp şifrelenmemiş sürüm olarak kaydederseniz düzenlenebilir eşdeğer bir kopya elde edebilirsiniz
[1] https://blog.adobe.com/en/publish/2022/01/31/20-years-of-tra... içindeki “More than just transparency” bölümü
[2] https://blog.didierstevens.com/2008/05/07/solving-a-little-p...
[3] https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandard... sayfa 61
[4] Örneğin pypdf kütüphanesini kullanan bir betik
O dönemin ünlü cracking rehberlerinden biri, izinleri kontrol eden fonksiyonu yamalayarak resmi okuyucunun DRM’ini kaldırma yöntemiydi
Bu konu periyodik olarak gündeme geliyor; çoğu kişi PDF’yi delinmesi zor bir ikili format sanıyor ama aslında öyle değil
PDF, farklı tiplerden oluşan bir nesne grafiğidir ve tiplerin kendisi resmi spesifikasyonda iyi anlatılmıştır. Bunu eğlence olsun diye okuyan eziyetli bir zevkim var
Her zaman önerdiğim şey, yazarın yaptığı gibi PDF’yi sıkıştırılmış veri içermeyen bir sürüme dönüştürmek. Tercih ettiğim araç mutool;
mutool clean -d in.pdf out.pdfkullanmanız yeterli. Sonra içine baktığınızda beklediğinizden daha fazla kısmı takip edebildiğinize şaşırırsınızYazıda sayfa nesnesine bakıp kaynakları kontrol etme adımı atlanmış. İçerik akışında kullanılan font adının gerçek alt nesneyle bağlandığı yer orasıdır
Ayrıca atlanan önemli bir nokta da, çoğu fontun PDF’nin içine alt küme olarak gömülmesidir. Fontta yalnızca gerekli glifler tutulur. Yeniden kodlama genelde burada gerçekleşiyor gibi görünüyor; ToUnicode ise metin kopyalamayı veya PDF içinde aramayı mümkün kılmak için korunuyor. Kullanıcı açısından bulunması iyi bir unsur ve benim deneyimime göre çoğunlukla var ve doğru oluyor
Zaten en başta salt okunur format yapma tasarım felsefesi hatalıydı. İnsanların ilk isteyeceği özellik bariz değil mi
Bulut sağlayıcısı olmadan, yerel olarak iyi işlemenin yollarına dair başka içgörüleriniz var mı merak ediyorum. Özellikle tablolar söz konusu olduğunda
Şöyle yapılabiliyor:
pdf2ps a.pdfile PostScripta.psdosyasına dönüştürvim a.psile PostScript’i doğrudan düzenleps2pdf a.psile tekrar PDF’ye dönüştürYerleşik JavaScript veya animasyon gibi şeyler içeren karmaşık PDF’ler bu gidiş dönüşten sonra düzgün çalışmayabilir. Yine de sıradan belgelerde oldukça iyi çalışır. Filigran kaldırmak, kelime ve sayı değiştirmek kolaydır; aralıkları düzeltmek daha zordur. Elbette PostScript’i bir miktar bilmek gerekir
Çıktı doğru olsa bile sayfaları yeniden sıralamak, posta makinesi işlemi ve posta tasnifi için barkod uygulamak, rapor oluşturmak gerekirdi. Genellikle Perl ve başka araçlarla sayfalardan metin kazıyıp adresleri alırdık; PS çoğu zaman PDF’den çok daha kolaydı, ama “güvenli” PDF’lerde doğru glif eşlemesi olmadığında olduğu gibi çok kırılgan durumlar da olurdu
En kötü durumda müşteri tekil belge PDF’leri gönderirdi; bunları birleştirince çıktıda alt küme fontlar patlayıp yazıcının belleğini doldurur ve onu çökertirdi. O işi bıraktığımda da aynı kaynak fonttan gelen alt küme fontları birleştirip kaynaştıran kullanışlı bir araç yok gibiydi. Mümkün olmalı ve çok faydalı olurdu, ama buna bakacak zamanım ya da bilgim yoktu
Açıkçası PDF’nin karmaşıklığından fayda sağlayanların yalnızca zararlı yazılım geliştiricileri olduğu izlenimine kapılıyorum
Önemli bir nokta atlanmış gibi. PDF’nin sonunda dosya içindeki çeşitli nesnelerin bayt ofsetlerini saklayan bir tablo, yani çapraz başvuru tablosu bulunur
Dosyanın içini değiştirirseniz bu ofsetler genellikle değişir ve dosya bozulur. Yazı sanki yalnızca bir sayıyı başka bir sayıyla değiştirmekle ilgilenmiş; bu yüzden konum değişmemiş olabilir
Ancak genel olarak dosyanın ortasında ekleme, silme veya düzenleme yaparsanız xref tablosunu yeniden hesaplamak gerekir; bu nedenle doğrudan metin düzenlemektense bir kütüphane kullanmak çok daha kolay olur
qpdf özgün PDF yapısını yeniden kuruyor ve nesne numaralarını da olduğu gibi tutmaya çalışıyor gibi görünüyor, ama ofsetler tamamen yeniden hesaplanıyor
Yazarları bir gün anlatırsa formatın neden böyle olduğunu okumak isterim. Başta tamamen metin biçimi olarak tasarlanmış, sonra ikili verinin daha verimli olduğuna karar verilmiş gibi. Yalnız xref tablo girdilerinin uzunluğunun sabit olması gereği, bu varsayımla da biraz tuhaf şekilde örtüşüyor
mutool cleangibi bir şey çalıştırarak düzeltmek. İçerikten tamamen türetilebildiği için güvenliUzunluğu koruduğunuz sürece ikili dosyayı istediğiniz gibi değiştirebilirsiniz
Eskiden kullandığım bir yazılım sunucuda kimlik doğrulaması yapıyordu ama tüm işlem istemcide gerçekleşiyordu. İstemci sunucuda doğrudan SQL çalıştırıyordu; sunucu da yalnızca bu istemcinin satın alınan lisans sayısını aşıp aşmadığını kontrol ediyordu
Disassembler’dan geçirip kontrol eden kısmı bulabiliyor, o kısmı doğrudan JMP ile değiştirip kalan boşluğu NOP ile doldurabiliyordum
qpdf’nin
--qdfmodunu kullanırken önemli bir adım eksik gibi. Düzenleme bittikten sonra, tüm nesne ofsetlerini yeniden hesaplamak ve dosyanın sonundaki çapraz başvuru tablosunu yeniden oluşturmak için dosyayı fix-pdf yardımcı aracından geçirmek gerekir. Ancak bayt ekleyip çıkarmadan yalnızca yerinde değiştirdiyseniz bu bir istisnadırEğlenceli PDF gerçekleri arasında ilk 3 şöyle
[0] Örnek: https://lab6.com/2
PDF yolculuğuna devam edip daha fazla öğrenmek isterseniz, yakın zamanda hazırladığım dosya inceleme belgesini okuyabilirsiniz:
https://pdfsyntax.dev/introduction_pdf_syntax.html
İnsanların PDF konusunda sıkça gözden kaçırdığı şey, bazı açılardan Word belgesinden çok görüntü formatına daha yakın olduğudur. Belge düzenlemede Word belgesi, PDF ve görüntüler; müzikte DAW projesi, MIDI ve MP3 gibidir, yazılımda da Java kaynak kodu, JVM bytecode’u ve saf x86 makine diline benzer
PDF dosyasının ana amacı, neyin gösterileceğini veya yazdırılacağını gerçek bir görüntüden çok daha az baytla kusursuz biçimde açıkça belirtmektir. Belgeyi oluşturanın belge yapısındaki örüntüleri bildiği gerçeğinden yararlanarak, doğru ifade edildiğinde gerçek görüntü sıkıştırma algoritmalarından çok daha iyi sıkışmasını sağlar. Örneğin gerçek fonta erişiminiz varsa, her harf örneğini görüntünün bir parçası olarak koyup sıkıştırma algoritmasının tekrarları kendiliğinden azaltmasını ummaktansa, “bu karakterleri şu koordinatlara şu aralıklarla yerleştir” demek daha iyidir. Hangi karakterin hangi kelimeye ait olduğu, hatta hangi Unicode kod noktasının hangi font glifine karşılık geldiği, hedef yalnızca belge görüntüsünü verimli biçimde iletmekse temelde önemli değildir
Düzenlenebilir bir belge söz konusuysa, gösterimden çok içeriğin anlamsal yapısı çok daha önemli hale gelir. Metindeki belirli bir kesintinin birden çok boşluk mu, tablodaki bir sonraki sütun mu, yoksa bir görüntü yüzünden oluşmuş tuhaf bir sayfa yerleşimi mi olduğu önemlidir. Her sayfanın altındaki metnin yazar tarafından defalarca mı eklendiği, yoksa bir kez girilip altbilgi olarak mı ayarlandığı da önemlidir. Yeni bir paragraf ekleyip sayfa düzenini değiştirmek gerekiyorsa, bu sayfadaki son paragrafın dipnot olduğu için sonraki sayfaya taşınmaması gerektiği gerçeği önemlidir. Bir bölüm başlığı başka bir sayfaya taşınırsa içindekiler tablosunun otomatik güncellenmesi gerektiği önemlidir; bunun yazarın elle girdiği sıradan metinden ibaret olmaması gerekir
Yazıcı veya ekran açısından bunların hiçbir önemi yoktur. Kendisine söylenen şekilde yazdırır ya da gösterir. PDF’de dipnotların, bölüm başlıklarının, altbilgilerin ve içindekiler tablosunun özel olması gerekmez; bunlar anlamsız biçimlendirme uygulanmış metin de olabilir. Bu yüzden PDF’yi görüntüleme veya yazdırma dışındaki amaçlarla kullanmaya çalışırsanız %100 doğru olamaz. Elbette bunu telafi etmeye yönelik çabalar var ve PDF oluşturan programlar istedikleri meta veriyi serbestçe ekleyebilir, ama bu zorunlu değildir
Bu, PDF yazarlarının amaçladığı zihinsel model olmayabilir; ancak PDF’nin neden bu biçimde olduğunu anlamak için yararlı bir bakış açısıdır
PostScript yazıcıdan çıkarıldığında tam olarak aynı görünürdü; Type 1 fontlar kullanılırsa daha da iyi olabilirdi
Bunu yapmaya çalışan kişi PDF’nin özünü kaçırıyor. PDF bir sayfa tanımlama formatı olduğundan belge yapısını değil, yalnızca sayfa üzerindeki görünür izleri temsil eder
PDF’yi düzenlemeye çalışmayın; PDF’yi oluşturan kaynak belgeyi düzenlemelisiniz
Bir noktada, düzenlenmek üzere yapılmış belgeyi doğrudan göndermek “profesyonel olmayan” bir şey haline geldi ve sonunda bu duruma geldik
İsteğe bağlıdır ama erişilebilirlik için önerilir. Örneğin PDF/UA vardır. [1]’in 14.7–14.8 bölümlerine bakabilirsiniz
[1] https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandard...
PDF metnini doğrudan değiştiremezsiniz. Çünkü dizgici o değişikliği görmez. Acrobat’ın işaretleme araçları berbat değil, ama kâğıt ve kırmızı kalem kullanılan dönem kadar iyi de değil. Acrobat’ın “pencil” aracını kullanmadığınız sürece. Keşke bu kısım iyileşse
20 yıl önce bir gazetede baskı kalıbı sorumlusu olarak çalıştım. Milyon dolarlık iki Kodak kalıp “yazıcımız” vardı; gerçi yazıcı demek pek doğru değil. Doğru hatırlıyorsam kalıbın emülsiyonu ultraviyole ışığa maruz kalıyor ve kimyasal banyoda çözünüyordu
Kodak ekipmanı sık sık arıza yapardı ve patronum PostScript veya EPS dosyalarını doğrudan açıp sayfa düzeni yazılımının gönderdiği başlıkları ya da bozuk kısımları düzeltirdi. Sonra yine düzgün çalışırdı. Bu arada dev Alman ofset rotatif baskı makinemiz Linux çalıştırıyordu
Patronumun adı sanırım Bill’di. 17 yaşındaki beni Sigur Ros konserine götüren iyi bir insandı. PDF ile ilgisiz iki hikâye anlatmış oldum
Güzel yazı. Son yaklaşık 5 yıldır DocSpring [1] üzerinde çalışırken PDF belirtimini çok okudum, ama hâlâ sadece yüzeyini kazımışım gibi hissediyorum. qpdf harika bir araç; sevdiğim bir diğer araç da PDF yapısının derinlerine inebileceğiniz RUPS [2]
[1] https://docspring.com
[2] https://github.com/itext/i7j-rups