Saltar al contenido

¿Es posible producir un PDF con texto que no se puede copiar?

Hola usuario de nuestra web, hallamos la solución a tu interrogante, deslízate y la obtendrás a continuación.

Solución:

Además de convertir todos los textos en imágenes, un método que conozco es destruir los Cmaps de las fuentes. Nosotros podemos usar cmap paquete y un archivo cmap especial para este propósito. Este archivo cmap se genera dentro del entorno VerbatimOut.

(Advertencia: no tiene mucho sentido producir un PDF que no se pueda copiar. El OCR es muy fácil hoy en día).

% pdflatex is required
documentclassarticle
usepackage[resetfonts]cmap
usepackagefancyvrb
beginVerbatimOutot1.cmap
%!PS-Adobe-3.0 Resource-CMap
%%DocumentNeededResources: ProcSet (CIDInit)
%%IncludeResource: ProcSet (CIDInit)
%%BeginResource: CMap (TeX-OT1-0)
%%Title: (TeX-OT1-0 TeX OT1 0)
%%Version: 1.000
%%EndComments
/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CIDSystemInfo
<< /Registry (TeX)
/Ordering (OT1)
/Supplement 0
>> def
/CMapName /TeX-OT1-0 def
/CMapType 2 def
1 begincodespacerange
<00> <7F>
endcodespacerange
8 beginbfrange
<00> <01> <0000>
<09> <0A> <0000>
<23> <26> <0000>
<28> <3B> <0000>
<3F> <5B> <0000>
<5D> <5E> <0000>
<61> <7A> <0000>
<7B> <7C> <0000>
endbfrange
40 beginbfchar
<02> <0000>
<03> <0000>
<04> <0000>
<05> <0000>
<06> <0000>
<07> <0000>
<08> <0000>
<0B> <0000>
<0C> <0000>
<0D> <0000>
<0E> <0000>
<0F> <0000>
<10> <0000>
<11> <0000>
<12> <0000>
<13> <0000>
<14> <0000>
<15> <0000>
<16> <0000>
<17> <0000>
<18> <0000>
<19> <0000>
<1A> <0000>
<1B> <0000>
<1C> <0000>
<1D> <0000>
<1E> <0000>
<1F> <0000>
<21> <0000>
<22> <0000>
<27> <0000>
<3C> <0000>
<3D> <0000>
<3E> <0000>
<5C> <0000>
<5F> <0000>
<60> <0000>
<7D> <0000>
<7E> <0000>
<7F> <0000>
endbfchar
endcmap
CMapName currentdict /CMap defineresource pop
end
end
%%EndResource
%%EOF
endVerbatimOut

usepackagelipsum

begindocument

lipsum

enddocument

Luatex permite manipular fuentes en el define_font llamar de vuelta. Luaotfload facilita esto aún más con un gancho adicional que se instala justo después de que el cargador de fuentes haya terminado su trabajo: el
luaotfload.patch_font llamar de vuelta. Normalmente se utiliza para tareas serias y constructivas como establecer un par de dimensiones de fuente o garantizar la compatibilidad con versiones anteriores en las estructuras de datos. Por supuesto, también se puede abusar de trucos sucios como deshabilitar copiar y pegar.

En el punto donde el patch_font se aplica la devolución de llamada, la fuente ya está definida y lista para usar. Todas las tablas necesarias se crean y colocan en el lugar donde Luatex las espera. Entre estos se encuentra el characters tabla que contiene información preprocesada sobre los glifos. En el siguiente código modificamos el tounicode campo de cada glifo para que se asigne a una ubicación aleatoria dentro del rango ASCII imprimible. Tenga en cuenta que esto no afecta la forma y las métricas del glifo, ya que no están relacionadas con el punto de código real. Como consecuencia, el PDF contendrá texto legible que no se puede copiar.

Archivo de paquete obfuscate.lua:

packagedata = packagedata or  

local mathrandom    = math.random
local stringformat  = string.format

--- this is the callback by means of which we will obfuscate
--- the tounicode values so they map to random characters of
--- the printable ascii range (between 0x21 / 33 and 0x7e / 126)

local obfuscate = function (tfmdata, _specification)
  if not tfmdata or type (tfmdata) ~= "table" then
    return
  end

  local characters = tfmdata.characters
  if characters then
    for codepoint, char in next, characters do
      char.tounicode = stringformat ([[%0.4X]], mathrandom (0x21, 0x7e))
    end
  end
end

--- we also need some functions to toggle the callback activation so
--- we can obfuscate fonts selectively

local active = false

packagedata.obfuscate_begin = function ()
  if not active then
    luatexbase.add_to_callback ("luaotfload.patch_font", obfuscate,
                                "user.obfuscate_font", 1)
    active = true
  end
end

packagedata.obfuscate_end = function ()
  if active then
    luatexbase.remove_from_callback ("luaotfload.patch_font",
                                     "user.obfuscate_font")
    active = false
  end
end

Demostración de uso:

%% we will need these packages
input luatexbase.sty
input luaotfload.sty

%% for inspecting the pdf with an ordinary editor
pdfcompresslevel0
pdfobjcompresslevel0

%% load obfuscation code
RequireLuaModule obfuscate

%% convenience macro
def packagecmd #1directlua packagedata.#1

%% the obfuscate environment, mapping to Lua functions that enable and
%% disable tounicode obfuscation
def beginobfuscate packagecmd obfuscate_begin ()
def endobfuscate   packagecmd obfuscate_end   ()

%%···································································%%
%% Demo
%%···································································%%

%% firstly, load some fonts. within the “obfuscate” environment all
%% fonts will get their cmaps scrambled ...

beginobfuscate

  font mainfont   = "file:Iwona-Regular.otf:mode=base"
  font italicfont = "file:Iwona-Italic.otf:mode=base"

endobfuscate

%% ... while fonts defined outside will have the mapping intact

font boldfont       = "file:Iwona-Bold.otf:mode=base"
font bolditalicfont = "file:Iwona-BoldItalic.otf:mode=base"

%% now we can use them in our document like any ordinary font

mainfont
obfuscated text before italicfont     obfuscated too and after par
obfuscated text before boldfont       not obfuscated and after par
obfuscated text before bolditalicfont not obfuscated and after par

bye

Resultado en el visor de PDF:

resultado mostrado

Contraste esto con la salida de pdftotext:

rf2yC'I_J I_dI r_f{_ 9;H`bp<

Pero olvídese de todo esto inmediatamente y nunca ofusque un texto de producción; ¡no sea malo con sus lectores!


EDITAR
Debido a que el generoso donante de karma pidió específicamente una solución de contexto, la incluiré como un bono. Es mucho más elegante ya que se basa en el obsequios de fuentes
Mecanismo que permite aplicar posprocesadores a fuentes específicas que luego se pueden usar como características comunes de fuentes.

startluacode

local mathrandom    = math.random
local stringformat  = string.format

--- create a postprocessor

local obfuscate = function (tfmdata)
  fonts.goodies.registerpostprocessor (tfmdata, function (tfmdata)
    if not tfmdata or type (tfmdata) ~= "table" then
      return
    end

    local characters = tfmdata.characters
    if characters then
      for codepoint, char in next, characters do
        char.tounicode = stringformat ([[%0.4X]], mathrandom (0x21, 0x7e))
      end
    end
  end)
end

--- now register as a font feature

fonts.handlers.otf.features.register 
  name         = "obfuscate",
  description  = "treat the reader like a piece of garbage",
  default      = false,
  initializers = 
    base     = obfuscate,
    node     = obfuscate,
  


stopluacode

%%···································································%%
%% demonstration
%%···································································%%

%% we can now treat the obfuscation postprocessor like any other
%% font feature

definefontfeature [obfuscate] [obfuscate=yes]

definefont [mainfont]   [file:Iwona-Regular.otf*obfuscate]
definefont [italicfont] [file:Iwona-Italic.otf*obfuscate]

definefont [boldfont]       [file:Iwona-Bold.otf]
definefont [bolditalicfont] [file:Iwona-BoldItalic.otf]


starttext

  mainfont
  obfuscated text before italicfont     obfuscated too and after par
  obfuscated text before boldfont       not obfuscated and after par
  obfuscated text before bolditalicfont not obfuscated and after par

stoptext

Observaciones

Utilizo un pequeño script, que convierte todas mis fuentes en rutas. El script usa el primer parámetro como entrada de un .pdf-archivo y escribe la salida en un archivo con el mismo nombre y la extensión-rst.pdf

Necesita Ghostscript para que se ejecute mi script.

Implementación

Se ejecuta en bash

#!/bin/sh

GS=/usr/bin/gs

$GS -sDEVICE=pswrite        -dNOCACHE -sOutputFile=-        -q -dBATCH -dNOPAUSE "$1"       -c quit | ps2pdf - > "$1%%.*-rst.pdf"
if [ $? -eq 0 ]; then
    echo "Output written to $1%%.*-rst.pdf"
else
    echo "There were errors. See the output."
fi

use ps2write (en lugar de pswrite) estos días como se ve aquí.

Resultado

ingrese la descripción de la imagen aquí

valoraciones y comentarios

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *