Поскольку разные издатели используют разные методы «маркировки» PDF-файлов, вам необходимо убедиться, что вы сравниваете их без учета маркировки.
Вам также нужен эффективный метод для сравнения нового PDF со всеми уже загруженными PDF-файлами в случае, если вы повторно загружаете один и тот же PDF-файл, и, например, он помечен IP-адресом и / или отметкой даты и времени, как вы предлагаете. Вы не хотите использовать трудоемкий механизм сравнения, который сравнивает каждый новый PDF со многими уже загруженными PDF
Вам нужна утилита, которая удаляет каждую из возможных меток и генерирует хэш оставшихся данных. Вам нужно будет сохранить карту хэша → имя файла, которая может быть в простом файле, и если вычисленный хэш уже есть в файле, у вас есть дубликат (и удалить его или сделать все необходимое), и если хеш еще не существует там вы добавляете хеш и имя файла. Файл будет выглядеть примерно так:
6fcb6969835d2db7742e81267437c432 /home/anthon/Downloads/explanation.pdf
fa24fed8ca824976673a51803934d6b9 /home/anthon/orders/your_order_20150320.pdf
Этот файл небрежно мал по сравнению с оригинальными PDF-файлами. Если у вас есть миллионы PDF-файлов, вы можете сохранить эти данные в базе данных. Для эффективности вы можете включить размер файла и количество страниц ( pdfinfo | egrep -E '^Pages:' | grep -Eo '[0-9]*'
).
Вышесказанное выдвигает проблему удаления меток и создания хэша. Если вы знаете, откуда берется PDF, когда вызываете подпрограмму генерации хеша (то есть, если вы загружаете программно), вы можете точно настроить генерацию хеша, основываясь на этом. Но даже без этого есть несколько возможностей для генерации хеша:
- если метаданные заголовка и автора не пустые и не включают в себя неспецифические строки, такие как «Acrobat» или «PDF», вы можете сгенерировать хеш на основе только информации об авторе и заголовке. Используйте,
pdfinfo -E file.pdf | grep -E '^(Author:)|(Title:) | md5sum
чтобы получить хэш. Вы можете включить количество страниц в расчет хэша (' Pages:
' в pdfinfo
выводе).
- Если предыдущее правило не работает и PDF-файл содержит изображения, извлеките изображения и сгенерируйте хэш для объединенных данных изображений. Если изображения когда-либо содержат текст в нижнем колонтитуле или верхнем колонтитуле, например «Лицензия для пользователя Joe», перед вычислением хэша удалите количество строк X сверху или снизу. Если эта маркировка выделена каким-то большим серым фоновым текстом с буквами, это, конечно, не сработает, если только вы не отфильтруете пиксели, которые не являются полностью черными (для этого вы можете использовать
imagemagick
). Вы можете использовать pdfimages
для извлечения информации изображения во временный файл.
- если предыдущие правила не работают (потому что нет изображений), вы можете использовать,
pdftext
чтобы извлечь текст, отфильтровать маркировку (если вы отфильтровываете немного, это не проблема), а затем сгенерировать хеш на основе который.
Кроме того, вы можете сравнить размер файла старого файла, найденного с помощью хэша, и посмотреть, находится ли он в пределах определенных полей с новым файлом. Сжатие и ifference в строках (IP / date-time-stamp) должны приводить только к разнице менее одного процента.
Если вам известен метод, используемый издателем при определении хэша, вы можете напрямую применить «правильный» метод из вышеприведенного, но даже без этого вы можете проверить метаданные и применить некоторые эвристические методы или определить количество изображений в файле. и сравните это с количеством страниц (если они близко, у вас, вероятно, есть документ, состоящий из сканов). pdftext
на отсканированных изображениях PDF также имеет узнаваемый вывод.
В качестве основы для работы я создал пакет python, который находится на bitbucket и / или может быть установлен с использованием PyPIpip install ruamel.pdfdouble
. Это предоставляет вам pdfdbl
команду, которая выполняет сканирование, как описано выше, для метаданных, извлеченных изображений или текста.
Он не выполняет никакой фильтрации меток (пока) , но в файле readme описано, какие (два) метода для улучшения добавить.
Включенный файл readme:
ruamel.pdfdouble
этот пакет предоставляет pdfdbl
команду:
pdfdbl scan dir1 dir2
Это позволит перейти к каталогам, указанным в качестве аргумента, и для найденных PDF-файлов создать хеш на основе (по порядку):
- метаданные, если они уникальны
- изображения, если количество изображений
- текст
Это предполагает, что pdfinfo, pdfimages и pdftotext` из пакета poppler-utils доступны.
Создается «база данных», по ~/.config/pdfdbl/pdf.lst
которой проверяются дальнейшие проверки.
Удаление маркировки
В ruamel/pdfdouble/pdfdouble.py
Есть два способа , которые могут быть усилены , чтобы отфильтровать маркировки в формате PDF , которые делают их менее уникальным и сделать практически одни и те же файлы , чтобы иметь различные хэши.
Для текста метод PdfData.filter_for_marking
должен быть расширен для удаления и разметки строки, являющейся его аргументами, и возврата результата.
Для отсканированных изображений этот метод PdfData.process_image_and_update
необходимо усовершенствовать, например, обрезая нижнюю и верхнюю X-строчки изображений и удаляя любой серый фоновый текст, устанавливая все черные пиксели в белый цвет. Эта функция должна обновить хеш, переданный с использованием .update()
метода, передающего отфильтрованные данные.
ограничения
Текущая «база данных» не может обрабатывать пути, содержащие символы новой строки
Эта утилита в настоящее время только на Python 2.7.
Соответствующие IP строки могут быть заменены re
модулем Python :
import re
IPre = re.compile("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}"
"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])")
x = IPre.sub(' ', 'abcd 132.234.0.2 ghi')
assert x == 'abcd ghi'