Skip to content

Compress, encrypt, decrypt, and say what a file allows - #5

Merged
tannevaled merged 1 commit into
mainfrom
protect-verbs
Aug 25, 2026
Merged

Compress, encrypt, decrypt, and say what a file allows#5
tannevaled merged 1 commit into
mainfrom
protect-verbs

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Four verbs the reader has been able to support since it learned to encrypt on writing, and which nothing was offering.

func (d *Doc) Compress()
func (d *Doc) Encrypt(e reader.Encryption)
func (d *Doc) Decrypt()
func (d *Doc) Protection() (reader.Protection, bool)

and on the command line:

pdfops compress in.pdf out.pdf
pdfops encrypt -user letmein -owner iownit -allow print,copy in.pdf out.pdf
pdfops -password letmein decrypt in.pdf out.pdf
pdfops -password letmein permissions in.pdf
protection AES-256, revision 6
opened as  the user
allows     print, copy

Measured on the whole corpus, on the pages rather than the exit status

Every file is opened, written, compressed and read back; then encrypted, reopened with each password, and written out plain again. What is compared at every step is a hash of what every page says.

files            118833
compressed       118833
  smaller        118746
  size           35202918151 -> 33576501245 (95.4%)
encrypted        118833
round-tripped    118833
took             6m55s

Nothing failed, nothing panicked, and no page changed by a byte at any step.

Needs reader v0.4.0 for Document.Protection. 100% statement coverage, go vet and gofmt clean.

Four verbs the reader has been able to support since it learned to encrypt on
writing, and which nothing was offering.

Compress packs the objects into compressed streams and a cross-reference
stream, which is what every writer since 2003 does. Over the whole corpus:
118 833 of 118 833 files come out with the same pages, 118 746 of them smaller,
35.2 GB down to 33.6 GB — 95.4% of what they were.

Encrypt protects the file that will be written, with either the current method
or the one readers from before 2008 understand. Decrypt writes it back out
without protection. Protection says how the file that was read was protected,
which is what the new permissions verb prints: the method in words, which
password opened it, and what it allows.

The whole corpus goes through all three: 118 833 files compressed and read
back with the pages byte for byte the same, 118 833 encrypted and refused
without a password and opened by both of them, 118 833 decrypted back to the
pages they started as. Nothing failed and nothing panicked.
@tannevaled
tannevaled merged commit d1f436c into main Aug 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant