Qual é o menor PDF válido possível?

139

Por simples curiosidade, tendo visto o menor GIF , qual é o menor arquivo PDF válido possível?

reticular
fonte
Depende de como você o cria. Provavelmente, você poderá escrever um menor (em um editor) do que o que um aplicativo geraria.
devnull
Tente alimentar "showpage" (sem aspas) para ghostscript ou ps2pdf.
devnull

Respostas:

194

Este é um problema interessante. Tomando o livro, você pode começar com isso:

%PDF-1.0
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 3 3]>>endobj
xref
0 4
0000000000 65535 f
0000000010 00000 n
0000000053 00000 n
0000000102 00000 n
trailer<</Size 4/Root 1 0 R>>
startxref
149
%EOF

que são 291 bytes de alegria em PDF. O Acrobat abre, mas reclama um pouco. Há uma página e ela é de 3/72 "quadrada, o mínimo permitido pelas especificações.

No entanto, o Acrobat X nem se preocupa mais com a tabela de referência cruzada, para que possamos resolver isso:

%PDF-1.0
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 3 3]>>endobj
trailer<</Size 4/Root 1 0 R>>

O Acrobat reclama, mas abre. Agora estamos em 178 bytes. Acontece que você não precisa desse tamanho / tamanho no trailer. Agora estamos em 172:

%PDF-1.0
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 3 3]>>endobj
trailer<</Root 1 0 R>>

Acontece que você não precisa de todos aqueles elementos irritantes / Type em seus dicionários:

%PDF-1.0
1 0 obj<</Pages 2 0 R>>endobj 2 0 obj<</Kids[3 0 R]/Count 1>>endobj 3 0 obj<</MediaBox[0 0 3 3]>>endobj
trailer<</Root 1 0 R>>

Agora estamos em 138 bytes.

Acontece também que, quando a especificação diz "deve ser uma referência indireta" e / Count é necessária, e o cabeçalho "deve" ser% PDF-1.0, eles estão fazendo sugestões soltas. Este é o menor que eu poderia fazer e abri-lo no Acrobat X:

%PDF-1.
trailer<</Root<</Pages<</Kids[<</MediaBox[0 0 3 3]>>]>>>>>>

70 bytes.

Agora, meu editor usa a disciplina de nova linha do Windows, mas o Acrobat aceita as convenções do Windows, Mac ou Unix, portanto, usando um editor hexadecimal, substituí o \ r \ n por \ re removi a última nova linha, o que me deixa com 67 bytes

25 50 44 46 2D 31 2E 0D 74 72 61 69 6C 65 72 3C 
3C 2F 52 6F 6F 74 3C 3C 2F 50 61 67 65 73 3C 3C 
2F 4B 69 64 73 5B 3C 3C 2F 4D 65 64 69 61 42 6F 
78 5B 30 20 30 20 33 20 33 5D 3E 3E 5D 3E 3E 3E 
3E 3E 3E 

Tentei tirar o último dicionário final (>>), mas o Acrobat não teria isso. A leitura de PDF incorporada ao Google Chrome (FoxIt) não a abrirá.

Como PostScript (HA! Vê o que eu fiz lá?), Se você autorizar o Acrobat a "reparar" o arquivo, ele atinge até 3550 bytes, a maioria dos metadados opcionais, mas deixa para trás várias violações claras das especificações.

plinto
fonte
25
Acontece também que, quando a especificação diz "deve ser uma referência indireta" e / Count é necessária, e o cabeçalho "deve" ser% PDF-1.0, eles estão fazendo sugestões soltas. Não, essas não são sugestões frouxas, são requisitos de validade. Mesmo que alguns visualizadores de PDF não os imponham, não segui-los implica invalidez, e o OP solicitou um PDF válido.
Mkl
23
Aceito porque a resposta começa com o minimum allowed by the spece depois vai além. Ótima resposta, obrigado! :)
meshy
plith, essa é uma resposta incrível. Agora, que tal o menor pdf válido com uma linha de texto, como "Hello World". Eu pensei que seria tão simples quanto adicionar {stream BT ("Hello World") ET endstream}, mas até agora não consegui fazer o Acrobat feliz.
neonzeon
1
Essa é a especificação. O gráfico de objetos em PDF possui ciclos.
plinth
1
@towi Sua versão codificada em base64 \nestá incorporada e, quando decodificada em base64, não fornece o conteúdo correto do arquivo.
30516 Christopher Schultz
19

Não consegui abrir o exemplo do olá mundo.

Para um arquivo pequeno com conteúdo de texto:

%PDF-1.2 
9 0 obj
<<
>>
stream
BT/ 9 Tf(Test)' ET
endstream
endobj
4 0 obj
<<
/Type /Page
/Parent 5 0 R
/Contents 9 0 R
>>
endobj
5 0 obj
<<
/Kids [4 0 R ]
/Count 1
/Type /Pages
/MediaBox [ 0 0 99 9 ]
>>
endobj
3 0 obj
<<
/Pages 5 0 R
/Type /Catalog
>>
endobj
trailer
<<
/Root 3 0 R
>>
%%EOF
Alan Riddell
fonte
2
Isso não vai funcionar, você precisa definir um recurso de fonte e selecioná-lo no conteúdo da página para que o texto seja exibido.
yms 21/08/2015
2
esse arquivo é aberto no Mac OS X El Capitan, enquanto a resposta mais classificada com o PDF1.0 não.
Devy
12
Também abre sob cromo, dados: aplicação / pdf; base64, JVBERi0xLjIgCjkgMCBvYmoKPDwKPj4Kc3RyZWFtCkJULyA5IFRmKFRlc3QpJyBFVAplbmRzdHJlYW0KZW5kb2JqCjQgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL1BhcmVudCA1IDAgUgovQ29udGVudHMgOSAwIFIKPj4KZW5kb2JqCjUgMCBvYmoKPDwKL0tpZHMgWzQgMCBSIF0KL0NvdW50IDEKL1R5cGUgL1BhZ2VzCi9NZWRpYUJveCBbIDAgMCA5OSA5IF0KPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1BhZ2VzIDUgMCBSCi9UeXBlIC9DYXRhbG9nCj4 + CmVuZG9iagp0cmFpbGVyCjw8Ci9Sb290IDMgMCBSCj4 + CiUlRU9G
Lucas Rehmann
8

Eu pensei em fazer um pdf menor que exibisse "Hello World". O texto está no canto inferior esquerdo. Desculpe pela fonte de 9 pontos, qualquer uma maior custaria um byte extra :)

172 bytes para o Adobe Reader X (se salvos com novas linhas apenas de alimentação de linha e nenhuma nova linha ou byte nulo à direita):

%PDF-1.
1 0 obj<</Kids[<</Parent 1 0 R/Resources<<>>/Contents 2 0 R>>]>>endobj 2 0 obj<<>>stream
BT/ 9 Tf(Hello World)' ET
endstream
endobj trailer<</Root<</Pages 1 0 R>>>>

120 bytes para o visualizador de PDF incorporado do Chrome:

%PDF 1 0 obj<</Pages<</Kids[<</Contents<<>>stream
BT 9 Tf(Hello World)' ET endstream>>]>>>>endobj trailer<</Root 1 0 R>>

Para ver isso facilmente no Chrome, cole esse URI na barra de endereço (a SO não permitirá que eu faça um link para ele e nem funcionará em outros navegadores):

data:application/pdf,%25PDF%201%200%20obj%3C%3C%2FPages%3C%3C%2FKids%5B%3C%3C%2FContents%3C%3C%3E%3Estream%0ABT%209%20Tf(Hello%20World)'%20ET%20endstream%3E%3E%5D%3E%3E%3E%3Eendobj%20trailer%3C%3C%2FRoot%201%200%20R%3E%3E
Hugh Allen
fonte
2
Bem pequeno. ;) Não é válido, porém, de acordo com as especificações.
Mkl
8
Não será aberto no Chrome para mim.
Luke Rehmann
0

Em Java, use isto:

 private static String samplepdf = "255044462D312E0D747261696C65723C3C2F526F6F743C3C2F50616765733C3C2F4B6964735B3C3C2F4D65646961426F785B302030203320335D3E3E5D3E3E3E3E3E3E";

e depois

byte[] bytes = hexStringToByteArray(samplepdf);

...

public byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                + Character.digit(s.charAt(i + 1), 16));
    }
    return data;
}
Martin Šimon
fonte
O OP solicitou o menor arquivo PDF válido possível ; o seu não é válido de acordo com as especificações.
mkl 02/07