28

If I run pdflatex on the same .tex file, the resulting PDF files are not bitwise identical. How can I achieve that?

Minimal example:

\documentclass{article}

\usepackage[pdftex]{hyperref}

\hypersetup{    pdfcreationdate={D:20131010120000},     pdfmoddate={D:20131010120000} }

\begin{document} foo \end{document}

If I create two PDF files from this example, create hexdumps with xxd and then compare these two hexdumps, this is the result:

--- 1   2013-10-10 15:04:17.228898334 +0200
+++ 2   2013-10-10 15:04:28.152898213 +0200
@@ -537,11 +537,11 @@
 0002180: 2f53 697a 6520 3138 0a2f 5720 5b31 2032  /Size 18./W [1 2
 0002190: 2031 5d0a 2f52 6f6f 7420 3135 2030 2052   1]./Root 15 0 R
 00021a0: 0a2f 496e 666f 2031 3620 3020 520a 2f49  ./Info 16 0 R./I
-00021b0: 4420 5b3c 3044 3938 3745 4533 3745 3642  D [<0D987EE37E6B
-00021c0: 4344 4234 3838 3333 4237 4636 3434 3335  CDB48833B7F64435
-00021d0: 3134 3443 3e20 3c30 4439 3837 4545 3337  144C> <0D987EE37
-00021e0: 4536 4243 4442 3438 3833 3342 3746 3634  E6BCDB48833B7F64
-00021f0: 3433 3531 3434 433e 5d0a 2f4c 656e 6774  435144C>]./Lengt
+00021b0: 4420 5b3c 3439 4644 3841 3445 3241 3439  D [<49FD8A4E2A49
+00021c0: 3434 4332 3244 4442 4536 4132 3534 3139  44C22DDBE6A25419
+00021d0: 3238 4334 3e20 3c34 3946 4438 4134 4532  28C4> <49FD8A4E2
+00021e0: 4134 3934 3443 3232 4444 4245 3641 3235  A4944C22DDBE6A25
+00021f0: 3431 3932 3843 343e 5d0a 2f4c 656e 6774  41928C4>]./Lengt
 0002200: 6820 3632 2020 2020 2020 2020 0a2f 4669  h 62        ./Fi
 0002210: 6c74 6572 202f 466c 6174 6544 6563 6f64  lter /FlateDecod
 0002220: 650a 3e3e 0a73 7472 6561 6d0a 78da 6360  e.>>.stream.x.c`

As you can see, there are still some differences, but I am not able to find out what this is.

Any ideas?

4

1 Answer 1

20

The PDF file format knows the entry /ID in the trailer dictionary (for identifying a PDF file more or less). This entry is set by the binary/executable pdftex and cannot be controlled at macro level. pdftex uses the MD5 checksum of the current time and the file name with the current path for the value of /ID.

If you want to compare the PDF files, the /ID lines can be filtered out:

$ grep -av ^/ID datei1.pdf > datei1.pdf-no-id
$ grep -av ^/ID datei2.pdf > datei2.pdf-no-id
$ diff datei1.pdf-no-id datei2.pdf-no-id

BTW, the minimal example sets the creation and modification times for the PDF information entries. Also the time commands at TeX level can be configured:

\year=2013
\month=10
\date=10
\time=\numexpr 12*60 + 0\relax

Or without redunancy:

\newcount\TimeHour
\newcount\TimeMin 

\year=2013
\month=10
\day=10
\TimeHour=17
\TimeMin=40

\time=\numexpr\TimeHour*60+\TimeMin\relax
\makeatletter
\edef\TimeString{%
  D:\the\year\two@digits\month\two@digits\day
  \two@digits\TimeHour\two@digits\TimeMin 00%
}
\makeatother

\documentclass{article}
\usepackage{hyperref}
\hypersetup{
  pdfcreationdate=\TimeString,
  pdfmoddate=\TimeString,
}

\begin{document}
  \today
\end{document}
4
  • 1
    Thank you very much for answer. But is a PDF with the /ID filtered out still a 100% valid PDF file?
    – Peter Ruge
    Oct 10, 2013 at 16:49
  • @PeterRuge: Yes. Oct 11, 2013 at 12:45
  • 3
    @PeterRuge: The PDF specification says about the /ID entry in the trailer that this entry is "optional, but strongly recommended (PDF 1.1)". Since pdfTeX writes the trailer at the end of the PDF file, the file offsets of the objects and the trailer are not invalidated by removing the /ID entry. But the line might contain other stuff, such as the end of the trailer dictionary. And removing it invalidates the file as PDF file. Therefore I recommend to only remove /ID [<...> <...>] or to replace it with spaces. Oct 12, 2013 at 14:19
  • 2
    Just for the record, since May 2016 pdftex has new primitives which focus of PDF reproducibility. With these primitives you can suppress the /ID and change the /CreationDate and /ModDate directly. See this question. Apr 3, 2019 at 22:15

Not the answer you're looking for? Browse other questions tagged .