Оскільки різні видавці використовують різні способи "маркування" 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 містить зображення, витягніть зображення та створіть хеш на комбінованих даних зображення. Якщо зображення коли-небудь містять текст у нижньому колонтитулі чи заголовку, наприклад "Ліцензований користувач Джо", перед обчисленням хеша зніміть X число рядків у верхній або нижній частині. Якщо ця позначка є у великому помаранчевому кольоровому тексті, це звичайно не буде працювати, якщо ви не відфільтруєте пікселі, які не є абсолютно чорними (для цього ви могли б скористатися
imagemagick
). Ви можете pdfimages
витягти інформацію про зображення у тимчасовий файл.
- якщо попередні правила не працюють (оскільки немає зображень), ви можете використовувати
pdftext
для вилучення тексту, відфільтрувати маркування (якщо ви відфільтруєте трохи на багато, це не проблема), а потім генерувати хеш на основі що.
Крім того, ви можете порівняти, чи розмір старого файлу знайдений через хеш, і побачити, чи знаходиться в певних полях з новим файлом. Стиснення та різниці в рядках (IP / дата-час-штамп) повинні спричинити лише менший відсоток різниці.
Якщо ви знаєте метод, який видавець використовує при визначенні хеша, ви можете безпосередньо застосувати «правильний» метод вищезазначеного, але навіть без цього ви можете перевірити метадані та застосувати певну евристику або визначити кількість зображень у файлі і порівняйте це з кількістю сторінок (якщо вони близькі, напевно, у вас є документ, що складається з сканів). pdftext
для сканованих зображень PDF-файли також мають впізнаваний вихід.
В якості основи для роботи я створив пакет python, який знаходиться в бітбукеті та / або може бути встановлений з PyPI за допомогою pip 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-рядки, що відповідають 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'