PDF: Formato Portátil de Documento para Documentos Multiplataforma
PDF (Portable Document Format) es el estándar ISO 32000 para intercambio de documentos, asegurando renderización consistente en todos los dispositivos y sistemas operativos. Desarrollado originalmente por Adobe (1993), PDF ahora es independiente de vendedor y ubicuo en negocios, legal, sanidad y gobierno. Comprender la estructura PDF es esencial para crear documentos seguros, accesibles, búsquedables y conformes.
Estructura de Documento PDF: Objetos y Primitivos
Cada archivo PDF es una colección de objetos—strings, números, arrays, diccionarios y streams:
%PDF-1.4 (encabezado con versión)
1 0 obj (ID de objeto 1, generación 0)
<< /Type /Catalog /Pages 2 0 R >> (diccionario con referencia a objeto 2)
endobj
2 0 obj (nodo del árbol de páginas)
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
endobj
3 0 obj (objeto de página)
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >>
endobj
4 0 obj (flujo de contenido)
stream
BT
/F1 12 Tf
100 700 Td
(¡Hola, Mundo!) Tj
ET
endstream
endobj
xref (tabla de referencias cruzadas)
0 5
0000000000 65535 f
0000000009 00000 n
0000000074 00000 n
0000000133 00000 n
0000000229 00000 n
trailer (diccionario trailer)
<< /Size 5 /Root 1 0 R >>
startxref
365
%%EOF
Tipos de objetos clave:
| Tipo | Ejemplo | Propósito |
|---|---|---|
| Booleano | true, false |
Lógica |
| Número | 42, 3.14 |
Coordenadas, tamaños, tamaños de fuente |
| String | (Hola), <48656C6C6F> |
Texto, datos binarios |
| Name | /Type, /Catalog |
Claves de diccionario |
| Array | [0 0 612 792] |
Dimensiones de página (x0, y0, x1, y1) |
| Diccionario | << /Type /Page >> |
Propiedades de objeto |
| Stream | stream…endstream |
Datos de imagen, contenido de página |
| Null | null |
Referencia vacía |
| Referencia | 2 0 R |
Puntero a objeto 2, generación 0 |
Composición de Página: Flujos de Contenido y Gráficos
La apariencia visual de una página PDF se define mediante un flujo de contenido—una secuencia de operadores:
q (guardar estado de gráficos)
1 0 0 1 50 50 cm (matriz de transformación: trasladar 50,50)
/F1 12 Tf (establecer fuente F1, tamaño 12)
100 50 Td (mover posición de texto a 100, 50)
(Texto de Ejemplo) Tj (mostrar cadena de texto)
Q (restaurar estado de gráficos)
BT (iniciar texto)
/F1 12 Tf (seleccionar fuente)
100 700 Td (posición de texto)
(Línea 1) Tj (mostrar texto)
T* (siguiente línea — usa parámetro de leading)
(Línea 2) Tj
ET (fin de texto)
Operadores de gráficos comunes:
| Operador | Efecto |
|---|---|
m x y |
MoveTo (iniciar nueva ruta en x, y) |
l x y |
LineTo (dibujar línea a x, y) |
c x1 y1 x2 y2 x3 y3 |
CurveTo (Bézier cúbica) |
h |
ClosePath (conectar último con primero) |
S |
Stroke (dibujar contorno de ruta) |
f |
Fill (rellenar ruta) |
rg r g b |
SetRGBColor (0.0–1.0) |
k c m y k |
SetCMYKColor |
q |
Save graphics state |
Q |
Restore graphics state |
cm a b c d e f |
Matriz de transformación (escalar, rotar, trasladar) |
Estructura de Página: MediaBox, CropBox, Bleed y Trim
Cada página define múltiples coordenadas de caja:
/MediaBox [0 0 612 792] (página completa 8.5×11 pulgadas a 72 DPI)
/CropBox [20 20 592 772] (área de contenido visible — excluye márgenes)
/BleedBox [10 10 602 782] (área de sangre de impresión — marcas de impresora)
/TrimBox [20 20 592 772] (tamaño de corte final después de corte)
/ArtBox [50 50 562 742] (área de contenido para herramientas de diseño)
Flujo de trabajo típico:
- MediaBox: tamaño de página física (8.5×11")
- CropBox: área visible en visor PDF (excluye márgenes de impresora)
- BleedBox: se extiende más allá de TrimBox para sangre de impresión (0.125")
- TrimBox: tamaño final después de corte (8×10.5")
- ArtBox: lienzo de trabajo para diseñador
Compresión: FlateDecode y Flujos de Imagen
Los PDFs comprimen contenido mediante varios algoritmos:
FlateDecode (zlib/deflate):
stream
x\x9c+P0T0P04R048W04S040050\r\x0c\x1c+\x10O0\x12\x00\x00\x00\x00\x1f\xff
endstream
Aplica LZ77 + Huffman a datos de texto y vector (~40% reducción).
Incrustación de imagen (DCTDecode para JPEG):
stream
[bytes JPEG crudos—FFD8FFE0…FFD9]
endstream
Incrusta datos JPEG directamente (sin re-codificación), ahorrando ~3× almacenamiento vs. RGB crudo.
CCITT Group 4 (escaneo monocromático de 1 bit):
/Filter /CCITTFaxDecode
/K -1
/Columns 2550
Codifica escaneos bitonales (1 bit) (fax, escaneos de documento) a ratio ~30:1.
Cifrado: RC4 y AES
Los PDFs soportan contraseñas a nivel de usuario y propietario:
RC4 (heredado, 40/128 bits):
- Cifrado de flujo RC4 con hash MD5
- 40 bits: limitado, descifrable (para cumplimiento de exportación)
- 128 bits: adecuado para seguridad casual
AES (AES-128/256, recomendado):
- AES en modo CBC con relleno PKCS#5
- AES-128: clave de 128 bits derivada de contraseña de usuario (hash MD5)
- AES-256: clave de 256 bits, requiere PDF 2.0
Objeto de cifrado:
/Encrypt << /Filter /Standard /V 4 /R 4 /Length 128 /P -44
/O <hex-owner-password-hash> /U <hex-user-password-hash> >>
Permisos de acceso:
/P -44= no imprimir, no copiar, no rellenar formularios/P -1= todos los permisos (sin restricciones)/P -4= solo impresión de alta resolución
Firmas Digitales y Certificados
Los PDFs soportan certificados X.509 incrustados para firmas legales:
/Sig << /Type /Sig /Filter /Adobe.PPKLite /SubFilter /adbe.pkcs7.detached
/Name (Juan Pérez) /Reason (Aprobación) /Location (Madrid)
/M (D:20240101120000Z) /Contents <hex-PKCS7-data> >>
Flujo de trabajo de firma:
- Creador deriva hash del contenido de página (SHA-256)
- Firma hash con clave privada (RSA-2048)
- Incrusta estructura PKCS#7 con certificado de firmante + timestamp
- Destinatario verifica firma mediante certificado público del firmante
- Cualquier cambio de contenido invalida la firma
Autoridad de Marca Temporal (TSA): asegura validez de firma incluso después de que cert del firmante expire.
Campos de Formulario y AcroForm
Los formularios interactivos incrustan definiciones de campo:
/AcroForm << /Fields [7 0 R 8 0 R] /SigFlags 3 >>
7 0 obj
<< /Type /Annot /Subtype /Widget /FT /Tx /Rect [50 700 200 720]
/V (Valor Predeterminado) /DV (Valor Inicial)
/DA (0 0 0 rg /F1 12 Tf) >>
endobj
Tipos de campo:
| Tipo | Subtipos | Uso |
|---|---|---|
/Tx |
Texto | Entrada de texto en una línea |
/Ch |
Combo, List | Selección desplegable |
/Btn |
Push, Check, Radio | Botones |
/Sig |
— | Firma digital |
Metadatos y Accesibilidad (PDF Etiquetado)
Diccionario de Información del Documento:
/Info << /Title (Informe Q4 2024) /Author (Jane Smith)
/Subject (Resultados Financieros) /Keywords (ingresos, ganancia)
/CreationDate (D:20240101120000Z) >>
PDF Etiquetado (PDF/UA—Accesibilidad Universal):
/StructTreeRoot << /Type /StructElem /S /Document /K [1 0 R 2 0 R] >>
1 0 obj
<< /Type /StructElem /S /Paragraph /P 0 0 R /Pg 3 0 R >>
endobj
Habilita lectores de pantalla para navegar estructura de documento (encabezados, listas, tablas, texto alternativo para imágenes).
Motores de Renderización Comunes
| Motor | Propósito | Velocidad |
|---|---|---|
| Ghostscript | Rasterización del lado del servidor (PDF→PNG) | Media (basada en C) |
| PDFium | Visor PDF de Google Chrome | Rápida (C++, renderización incremental) |
| MuPDF | iOS/Android ligero | Muy rápida (eficiente en memoria) |
| iText 7 | Manipulación de PDF Java/C# | Media (basada en JVM) |
| PyPDF4/pypdf | Extracción de texto Python | Lenta (Python puro) |
Seguridad Práctica y Cumplimiento
PDF/A (archivo):
- Fuentes incrustadas, metadatos, perfiles de color
- Sin cifrado, referencias externas o JavaScript
- Adecuado para almacenamiento legal a largo plazo (20+ años)
PDF/UA (accesibilidad):
- Estructura etiquetada, texto alternativo, orden de tabulación lógico
- Destinos nombrados para marcapáginas
- Adecuado para cumplimiento de gobierno (Sección 508, EN 301 549)
PDF/X (intercambio de impresión):
- Colores CMYK, fuentes incrustadas, colores de mancha
- Sin transparencia, capas o JavaScript
- Adecuado para producción de impresión RIPs
PDF vs. Alternativas
| Formato | Codificación | Editabilidad | Cifrado | Tamaño |
|---|---|---|---|---|
| Modelo de objeto complejo | Limitada (bloqueada) | ✅ (AES-256) | 200 KB (doc) | |
| DOCX | ZIP + XML | ✅ (completa) | ✅ (solo Office 365) | 150 KB |
| PostScript | Operadores basados en pila | ❌ (solo fuente) | ❌ | 500 KB |
| TIFF | Raster de imagen | ❌ (raster) | ❌ | 5 MB (escaneado) |
| HTML | Marcado + CSS | ✅ (completa) | ❌ | 50 KB |
PDF domina para distribución debido a su consistencia de renderización, cifrado y soporte de firmas. Para edición colaborativa, DOCX es superior. Para archivo, PDF/A es requerido.
Creación y Manipulación de PDFs Programáticamente
Ghostscript (rasterización PDF→PNG):
gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=png16m -r300 \
-sOutputFile=page-%d.png entrada.pdf
Python (pypdf):
from pypdf import PdfReader
reader = PdfReader('entrada.pdf')
for page in reader.pages:
print(page.extract_text())
PDFtk (fusionar, dividir, sello):
pdftk A=entrada1.pdf B=entrada2.pdf cat A B output fusionado.pdf
pdftk entrada.pdf burst output página-%d.pdf
iText 7 (Java):
PdfWriter writer = new PdfWriter("salida.pdf");
PdfDocument doc = new PdfDocument(writer);
Document document = new Document(doc);
document.add(new Paragraph("¡Hola, Mundo!"));
document.close();
La longevidad, seguridad e interoperabilidad de PDF lo hacen indispensable para flujos de trabajo comerciales, legales y de gobierno.