Где файлы .doc хранят изображения?
doc
Word на самом деле архивируются и затем помещаются в контейнерный формат. Они хранят медиафайлы где-то в этом формате скомпилированного файла, вероятно, сразу после заголовка формата doc
. После данных изображения, ваш настоящий документ в виде zip-совместимой папки.
Поэтому, когда вы пытаетесь разархивировать файл doc
, в начале вы получаете избыточное количество байтов. Это ваши изображения (плюс заголовок формата). Теперь вы можете попытаться unzip
файл и проверить избыточное количество байтов.
charon:test werner$ unzip -c images.doc > /dev/null
warning [images.doc]: 47166 extra bytes at beginning or within zipfile
charon:test werner$ unzip -c noimages.doc > /dev/null
warning [noimages2.doc]: 6060 extra bytes at beginning or within zipfile
В ходе тестирования я обнаружил, что заголовок "незашифрованных" документов Word имеет размер 6060 байт (хотя некоторые немного больше). Мы можем попытаться использовать его для определения, есть ли изображение внутри документа. Скажем так, 8000 байт - поскольку реальные изображения определенно будут иметь более нескольких килобайт.
Как насчет файлов .docx?
С форматом Office 2007 (docx
) это намного проще. Это настоящие заархивированные файлы, и любой файл Word, содержащий любые встроенные носители (изображения, видео), будет содержать file.docx/word/media
. Итак, нам просто нужно распаковать файлы docx
и проверить, существует ли этот каталог.
Скрипт для проверки изображений
Создайте новый пустой файл, назовите его docx-images.rb
и вставьте следующее содержимое:
#!/usr/bin/env ruby
require 'open3'
TEMPDIR = "/tmp/word/"
# check for docx files
Dir.glob("**/*.docx").each do |file|
system("rm -rf '#{TEMPDIR}'")
system("unzip '#{file}' -d #{TEMPDIR} > /dev/null")
if File.directory?("#{TEMPDIR}/word/media/")
puts file
end
end
# check for doc files
Dir.glob("**/*.doc").each do |file|
stdin, stdout, stderr = Open3.popen3("unzip -c '#{file}' > /dev/null")
info = stderr.readlines[0]
info = info.gsub(" extra bytes at beginning or within zipfile", "").gsub(/warning\s\[.*\]:\s+/, "")
if info.to_i > 8000 # assume a little more than usual header size
puts file
end
end
Сохраните его где-нибудь, желательно в папке, откуда вы хотите начать поиск файлов docx
, возможно, в папке « Documents
».
Теперь откройте Terminal.app и используйте для этого cd ~/Documents
.
Введите ruby docx-images.rb
, и он рекурсивно просканирует вашу папку « Documents
» на наличие файлов docx
и doc
. Он разархивирует первые в /tmp/word
и проверит, содержат ли они встроенные носители. Последние просто разархивируются в /dev/null
, что не оставляет следов.
Вы получите список тех, у кого есть встроенный носитель.
доказательство
Чтобы доказать, что это работает, я создал четыре файла. Один с изображениями, другой без изображений - как doc
и docx
:
Затем запустим скрипт:
charon:test werner$ ruby docx-images.rb
images.docx
images.doc
Очевидно, что сценарий можно улучшить, чтобы он проверял наличие реальных изображений в этой папке media
, но вряд ли он существует, если в файле действительно нет носителя. То же самое касается проверки 6060 байтов. Это взлом, но у меня это работает.
Конечно, сценарий зависит от реализации unzip
на соответствующей системе, но он работает для версии OS X.