О скрипте:
Скрипт для блокировки чата, чтобы разблокировать чат необходимо ввести символы с картинки (капчи), которая автоматически генерируется php скриптом на веб сервере. Основа для скрипта lua взята из ChatGuard (так как велосипед изобретать не хочется).
Как это работает?
С помощью библиотеки md5 для PtokaX, есть возможность генерировать необратимые md5 хэши. Этим я и воспользовался, генерируется "пароль" из 3х случайных символов символов:
local pass = string.char(math.random (1, 255))..string.char(math.random (1, 255))..string.char(math.random (1, 255));
Далее получаем его md5 хэш по принципу md5(md5(pass)+salt), т.е. получаем хэш пароля, прибавляем к нему соль (salt), и получаем хэш всего этого, после берём 4 символы из серединки:
local hash1 = md5.sumhexa(md5.sumhexa(pass)..Salt);
if string.len(hash1) ~= 4 then hash1 = string.sub(hash1, string.len(hash1)/2-3, string.len(hash1)/2); end;
Полученный результат (hash1) прогоняем ещё раз по такому же принципу и результат записываем в hash2:
local hash2 = md5.sumhexa(md5.sumhexa(hash1)..Salt);
if string.len(hash2) ~= 4 then hash2 = string.sub(hash2, string.len(hash2)/2-3, string.len(hash2)/2); end;
Теперь у нас 2 необратимых хэша. Первый (hash1) - хэш пароля, а второй (hash2) - хэш хэша пароля. hash1 мы передаём php скрипту на веб сервере в строке с параметром h, а hash2 мы оставим у себя для проверки.
Скрипт генерирует из переданного ему хэша, хэш по нашему принципу и мы получаем опять же хэш хэша пароля, т.е. тоже самое что и hash2 в нашем скрипте, только на php:
$Hash = md5(md5($Pass).$Salt);
if (strlen($Hash) != 4) {$Hash = substr($Hash,strlen($Hash)/2-4,4);}
После этого скрипт генерирует картинку (капчу), со сгенерированным хэшем, а пользователь вводить его с картинки в чат:
Если пользователь ввёл правельные 4 символы то блокировка снимается, иначе вопрос повторяется:
Плюс всей системы в том что боты не смогут просканировать текст и получить число или слово для разблокировки, а получить символы с картинки с шумами не очень то и просто, да и некто не будет так изощрятся ради флуда.
Хэши необратимые а значит получить исходный текст нельзя, хэшировать повторно для получаения hash2 тоже нельзя незная соль (salt), а на подбор уйдут годы.
Улучшения в генерации капчи:
Отключение\включение 3х случайных картинок (ради красоты, интереса и сложности прибавит)
Отключение\включение случайных смайлов в правом нижнем углу (ради красоты и сложности прибавит) (всего 10)
Отключение\включение генераций линий на заднем плане
Отключение\включение генераций случайных точек
Отключение\включение генераций линий на переднем плане
Теперь для каждого символа рандомно выбирается шрифт (всего 8, в папке fonts которые можно заменить по вкусу)
Каждый символ рандомно сдвигается по вертикали
Каждый символ рандомно наклоняется
Установка:
Файлы из папки ptokax кинуть в папку с устан0вленн0й патахой
Файлы из папки web кинуть на вебсервер
Обязательно измените переменные Salt в ChatGuard_captcha_api1.lua и md5Hash_img.php (достаточнео замены 1го символа)
кстати тест самого скрипта пока поработает на [url]dchub://89.178.56.206[/url], так что если интересно на него поглазеть заходите
Добавлено: 29 авг 2009, 12:38
Sunlight
Хороший скрипт, если несложно, переведи на луа1
Там за основу взят скрипт ChatGuard, я так понял, который под луа1 есть.
Добавлено: 29 авг 2009, 13:24
ASPIRIN++
Sunlight писал(а):если несложно, переведи на луа1
запросто)) только просплюсь 2е суток без сна
Добавлено: 31 авг 2009, 04:48
ASPIRIN++
всё всю ночь просидел ))) в результате весрия 0.9 под api1 и api2
Добавлено: 31 авг 2009, 14:50
Sunlight
Респект, все работает
Исправил пару опечаток только и переделал под себя.
Добавлено: 25 сен 2009, 23:45
Sunlight
Что нужно подправить чтобы не учитывался регистр букв? Ато на капче большие буквы, а вводить в чат нужно обязательно маленькими. Путаются люди.
Добавлено: 30 сен 2009, 20:50
Sunlight
Связался с автором, помог решить проблему:
Под апи1:
if US[sUser.sName].hash==arg then изменить на if string.lower(US[sUser.sName].hash)==string.lower(arg) then
if sData==US[sUser.sName].hash then изменить на if string.lower(sData)==string.lower(US[sUser.sName].hash) then