Форматы сжатия с хорошей поддержкой произвольного доступа в архивах?

Как вы можете видеть, люди предлагают вам максимально использовать подготовленные заявления. Это не так, но когда ваш запрос выполняется всего один раз за процесс, будет небольшое снижение производительности.

Я столкнулся с этой проблемой, но я думаю, что решил ее в очень сложном пути - как хакеры используют, чтобы избежать использования кавычек. Я использовал это в сочетании с эмулированными подготовленными заявлениями. Я использую его, чтобы предотвратить все возможные типы инъекций SQL.

Мой подход:

  • Если вы ожидаете, что ввод будет целым, убедитесь, что он действительно целое число. В языке с переменным типом, таком как PHP, этот очень важен. Вы можете использовать, к примеру, это очень простое, но мощное решение: sprintf("SELECT 1,2,3 FROM table WHERE 4 = %u", $input);
  • Если вы ожидаете чего-то еще от целого шестнадцатеричного значения. Если вы отбросите его, вы полностью избежите ввода. В C / C ++ есть функция, называемая mysql_hex_string() , в PHP вы можете использовать bin2hex() . Не беспокойтесь о том, что экранированная строка будет иметь размер в 2 раза по сравнению с исходной длиной, потому что даже если вы используете mysql_real_escape_string, PHP должен выделять одну и ту же емкость ((2*input_length)+1), что то же самое.
  • hex метод часто используется при передаче двоичных данных, но я не вижу причин, почему бы не использовать его во всех данных для предотвращения атак SQL-инъекций. Обратите внимание, что вам необходимо предварительно добавить данные с помощью 0x или использовать функцию MySQL UNHEX.

Так, например, запрос:

SELECT password FROM users WHERE name = 'root'

Будет:

SELECT password FROM users WHERE name = 0x726f6f74

или

SELECT password FROM users WHERE name = UNHEX('726f6f74')

Hex - идеальный выход.

Разница между функцией UNHEX и префиксом 0x

В комментариях было некоторое обсуждение, поэтому я, наконец, хочу дать понять. Эти два подхода очень похожи, но в некоторых отношениях они немного различаются:

Префикс ** 0x ** может использоваться только для столбцов данных, таких как char, varchar, text, block, binary, и т. д. Кроме того, его использование немного сложно, если вы собираетесь вставить пустую строку. Вам придется полностью заменить его на '', или вы получите сообщение об ошибке.

UNHEX () работает в любом столбце; вам не нужно беспокоиться о пустой строке.


Hex-методы часто используются в качестве атак

Обратите внимание, что этот шестиугольный метод часто используется как атака SQL-инъекции, где целые числа точно так же, как и строки mysql_real_escape_string. Тогда вы можете избежать использования кавычек.

Например, если вы просто делаете что-то вроде этого:

"SELECT title FROM article WHERE id = " . mysql_real_escape_string($_GET["id"])

атака может очень легко ввести вас . Рассмотрим следующий введенный код, возвращенный из вашего скрипта:

SELECT ... WHERE id = -1 union all select table_name from information_schema.tables

и теперь просто извлеките структуру таблицы:

SELECT ... WHERE id = -1 union all select column_name from information_schema.column где table_name = 0x61727469636c65

И тогда просто выберите нужные данные. Разве это не круто?

Но если кодер инъекционного сайта будет шестнадцатеричным, инъекция не будет возможна, потому что запрос будет выглядеть следующим образом: SELECT ... WHERE id = UNHEX('2d312075...3635')

54
задан Community 23 May 2017 в 02:09
поделиться

4 ответа

Я не знаю ни о каком формате сжатого файла, который поддерживал бы произвольный доступ к определенному местоположению в несжатых данных (хорошо, за исключением мультимедийных форматов), но можно варить собственное.

, Например, bzip2 сжатые файлы состоят из независимых сжатых блоков размера < 1 МБ распаковал, которые разграничены последовательностями волшебных байтов, таким образом, Вы могли проанализировать bzip2 файл, получить границы блока и затем просто распаковать правильный блок. Этому была бы нужна некоторая индексация для запоминания, где блоки запускаются.

однако, я думаю, что лучшее решение состояло бы в том, чтобы разделить Ваш файл на блоки по Вашему выбору и затем сжатие его с некоторым archiver, как zip или rar, которые поддерживают произвольный доступ к отдельным файлам в архиве.

18
ответ дан jpalecek 7 November 2019 в 08:03
поделиться

Я не уверен, было ли это практично в Вашей точной ситуации, но не могли Вы просто gzip каждый большой файл в меньшие файлы, сказать 10 МБ каждый? Вы закончили бы с набором файлов: file0.gz, file1.gz, file2.gz, и т.д. На основе данного смещения в рамках большого оригинала, Вы могли искать в файле, названном "file" + (offset / 10485760) + ".gz". Смещение в несжатом архиве было бы offset % 10485760.

3
ответ дан William Brendel 7 November 2019 в 08:03
поделиться

К формату gzip можно случайным образом получить доступ, если индекс был ранее создан, как он продемонстрирован на zlib's исходный код .

zran.c , который я имею, разрабатывают инструмент командной строки на zlib's zran.c, который создает индексы для gzip файлов: https://github.com/circulosmeos/gztool

Это может даже создать индекс для тихого роста gzip файл (например, журнал, созданный rsyslog непосредственно в формате gzip) таким образом уменьшающий в практике для обнуления времени создания индекса. Посмотрите -S (, Контролируют ), опция.

1
ответ дан 7 November 2019 в 08:03
поделиться

Поскольку сжатие без потерь в одних областях работает лучше, чем в других, если вы храните сжатые данные в блоках удобной длины BLOCKSIZE, даже если каждый блок имеет точно такое же количество сжатых байтов, некоторые сжатые блоки будут расширяться до гораздо более длинного фрагмента открытого текста, чем другие.

Вы могли бы посмотреть на «Сжатие: ключ к системам поиска текста нового поколения» Нивио Зивиани, Эдлено Сильва де Моура, Гонсало Наварро и Рикардо Баеза-Ятс в Компьютерный журнал , ноябрь 2000 г. http://doi.ieeecomputersociety.org/10.1109/2.881693

Их декомпрессор берет 1, 2 или 3 целых байта сжатых данных и распаковывает (используя список словаря) целое слово. Можно напрямую искать в сжатом тексте слова или фразы, что оказывается даже быстрее, чем поиск в несжатом тексте.

Их декомпрессор позволяет указать на любое слово в тексте обычным (байтовым) указателем и немедленно начать распаковку с этой точки.

Вы можете присвоить каждому слову уникальный двухбайтовый код, поскольку в вашем тексте, вероятно, меньше 65 000 уникальных слов. (В Библии KJV почти 13 000 уникальных слов).Даже если имеется более 65 000 слов, довольно просто присвоить первые 256 двухбайтовых кодовых «слов» всем возможным байтам, так что вы можете составить слова, которых нет в лексиконе 65 000 или около того «наиболее часто встречающихся» слова и фразы". (Сжатие, полученное за счет упаковки частых слов и фраз в два байта обычно стоит «расширения» изредка написания слова с использованием двух байтов на букву). Существует множество способов подобрать словарный запас «часто встречающихся слов и фраз», которые обеспечат адекватное сжатие. Например, вы можете настроить компрессор LZW, чтобы выгружать «фразы», ​​которые он использует более одного раза, в файл словаря, по одной строке на фразу, и запускать его по всем вашим данным. Или вы можете произвольно разделить несжатые данные на 5-байтовые фразы в файле словаря, по одной строке на фразу. Или вы можете разделить несжатые данные на настоящие английские слова и поместить каждое слово - включая пробел в начале слова - в файл лексики. Затем используйте команду «sort --unique», чтобы удалить повторяющиеся слова в этом файле лексики. (Выбор идеального «оптимального» словарного списка по-прежнему считается NP-трудным?)

Сохраните лексикон в начале вашего огромного сжатого файла, дополните его до некоторого удобного размера BLOCKSIZE, а затем сохраните сжатый текст - серию двухбайтовых «слов» - оттуда до конца файла. Предположительно, поисковик прочитает этот лексикон один раз и сохранит его в каком-либо формате для быстрого декодирования в ОЗУ во время распаковки, чтобы ускорить распаковку «двухбайтового кода» в «фразу переменной длины».Мой первый черновик будет начинаться с простого списка фраз, по одной строке, но позже вы можете переключиться на хранение лексики в более сжатой форме, используя какое-то инкрементное кодирование или zlib.

Вы можете выбрать любое случайное четное смещение в байтах сжатого текста и начать распаковку оттуда. Я не думаю, что возможно создать более детализированный формат сжатого файла с произвольным доступом.

3
ответ дан 7 November 2019 в 08:03
поделиться