#c #lzw
#c #lzw
Вопрос:
У меня есть два XML-файла, один из которых сжат с помощью LZW, другой — в виде обычного текста. Как я могу узнать, сжата она или нет?
Комментарии:
1. если вы знаете, что это XML, вы можете выполнить поиск грамматических подсказок XML в первых нескольких байтах, а затем проверить синтаксис. Если подсказки не найдены, вы можете попытаться посмотреть, есть ли какие-либо подсказки для сжатой строки LZW, и в общем случае просто попробуйте снова распаковать и проверить xml
2.
file
Знает ли команда, что у вас есть в этих сжатых файлах? Обычно он довольно хорошо разбирается в вещах и может дать подсказку, которую вы можете использовать. Какое сжатие LZW вы используете? Есть ли у нее какие-либо рамки или заголовки, подобныеgzip
does?3. @tadman Это хороший момент. Большинство программ сжатия вставляют волшебный заголовок в первые пару байтов, идентифицируя файл как сжатый файл.
Ответ №1:
Очевидным, что нужно сделать, было бы, конечно, передать строку в LZW-декомпрессор и посмотреть, есть ли ошибка и / или длина строки увеличивается примерно на 200%.
Кроме того, (правильно сформированная) строка LZW или файл помечаются магическим значением 0x1F 0x9D
. Конечно, можно сжать строку LZW и не включать магическое значение, но это только начало (очень легко проверить).
(Правильно сформированный) XML-документ должен начинаться с XML-объявления и должен начинаться с элемента, которому необязательно предшествует пробел. Объявления XML начинаются со строки <?xml
, а теги элементов должны начинаться с буквы.
Поэтому, если вы видите что-либо, кроме пробелов, перед тем, как встретить первый <
или если следующий следующий символ не является ни ?
или буквой (и только буквы и цифры следуют перед тем, как встретить a >
), то строка не может быть XML. Поскольку вы знаете, что строка представляет собой либо XML, либо сжатый XML, поэтому она должна быть сжата. Вероятно, для кого-то, у кого есть небольшая практика регулярных выражений, достаточно легко сжать это в шаблон из 10-15 символов.
Комментарии:
1. Может быть спецификация перед
<?
?2. @Yakk: Может быть, да. Не то чтобы это было строго «правильно», но это «допустимо», и с этим вы можете столкнуться, если при написании этого XML использовался редактор Windows. Спецификация, например
<?
, будет обозначать несжатую строку (и, учитывая, что они являются недопустимыми символами, считаются «пробелами» в более широком смысле).
Ответ №2:
Глупый простой тест: является ли первый символ a <
?
Комментарии:
1. Как ни странно, комментарии к вопросу дают некоторые ответы, и этот ответ — скорее комментарий. Я думаю, что, если вы не уверены в формате заголовка сжатого файла (или поврежденного файла?), У вас может быть 1/256 шанс, что первым символом сжатого файла является a
<
.2. LZW начинается с первых 256 «кодовых точек», представляющих самих себя, и без каких-либо других кодовых точек, поэтому первый символ в сжатом файле всегда будет таким же, как первый символ в исходном файле. Однако второе почти наверняка будет другим, и чем больше вы читаете, тем больше уверенности в том, что вы найдете различия (и даже символы, отличные от ASCII, или недопустимый UTF-8).
3. И, конечно, если файл не сжат, он может начинаться со спецификации.
4. Это было скорее решение «если все остальное не удастся», но мне нравится более элегантный подход Деймона.
Ответ №3:
Ищите недопустимые или бессмысленные символы (например, нулевой символ). Если они существуют, то они сжимаются.
Если нет, то либо это обычный XML, либо файл очень маленький (в противном случае это было бы маловероятно).
Ответ №4:
Это поможет, если вы хотите узнать, сжат ли он, чтобы вы могли распаковать файл и готовы использовать библиотеки для тяжелой работы:
Используйте библиотеку сжатия, чтобы всегда пытаться распаковать файл. Пусть он решит, был ли файл сжат. После этого передайте полученный файл в библиотеку xml и позвольте этой библиотеке решить, есть ли у вас допустимый и ожидаемый XML-файл. Если возможно, не воссоздавайте функциональность обычных библиотек, просто убедитесь, что вы правильно обрабатываете возвращенную информацию библиотек.