Доброго времени суток, хабровчане! Это мой первый пост на форуме, так что прошу строго не судить.
Коротко обо мне: студент, увлекаюсь электроникой, микроконтроллерами, и программированием. Однако, моя специальность ни коим образом не связана с It. Со мной покончено, переходим к сути.
Как и полагается любому техническому вузу – в нашем есть куча интернет ресурсов, которыми вуз чрезмерно гордится. Однако есть оборотная сторона медали – качество этих сервисов. А именно, если говорить про электронную библиотеку, о коей и пойдет речь в данной статье, то в ней напрочь отсутствует возможность скачивания pdf-версии нужной тебе методички, точнее она есть, но за это придется заплатить немало денЯк. Деньги далеко не маленькие (если говорить именно про цену за вузовские методички). Если же такой формат не устраивает, то можешь пользоваться онлайн библиотекой.
В онлайн библиотеке есть просмотрщик книг, через который можно читать литературу.
Просмотрщик оформлен максимально неудобно: долгое время не работал переход на определенную страницу книги, и книгу в 700 страниц приходилось перелистывать по страничке, что превращалось в адскую муку. Но самое ужасное в этом сайте то, что каждые 20 минут он просит авторизоваться по новой…
И теперь представьте картину: человек пытается подготовиться к контрольной по квантовой механике по методичкам преподавателя, объемом 700 страниц, где необходимый материал находится на 500, и может перелистывать по 5 страничек в минуту, и каждые 20 минут, его попытки приходится возобновлять.… В общем, жесть…. И вот после очередной неудачной попытки прочитать нужную главу, я решил, что пришло время положить конец данному произволу.
Первым делом, средствами браузера, была получена ссылка на необходимый ресурс с изображением страницы. Ссылка выглядела примерно следующим образом:
“http://www.<название сайта>/plugins/<название просмоторщика>/getDoc.php?Id=<id книги>&page=<номер страницы>”
После получения данной ссылки скачивание книги не составляет и труда:
Необходимо получить id книги (или лучше ссылку на нее)
Узнать количество страниц
В самом простом цикле for пробежаться по всем страницам, загрузив их на компьютер
Объединить фотографии в единый файл pdf
Радоваться
Собственно, к выполнению данных шагов я и приступил. В процессе работы выяснилось, что также, необходимым шагом является авторизация на самом ресурсе.
Самая первая версия программы выглядела максимально убого: я использовал java и библиотеку selenium для работы с сетью. Приложение получилось явно не user-friendly: запускалась только из IDEA, в которой ручками необходимо было вставлять ссылку на каждую книгу, также ручками забивать количество страниц. Более того, самым убожеством был тот факт, что приложение полностью имитировало пользователя:
Открывался сайт в браузере
Далее проводился поиск полей для логина и пароля и их заполнение
Затем переход по ссылке с первой страницей книги
И сочетание клавиш “CTRL”+”S”, нажатие на “Enter”….
В общем – фу! Нельзя так делать!
Но когда у тебя на носу контрольная по квантмеху, и так сойдет. Программа была написана минут за 20, и книжки она выкачивала долго, и иногда не все страницы, хуже того, после скачивания, опять же ручками приходилось объединять картинки в единый файл pdf….
Но, не спешите бросаться помидорами, данный кошмар в дальнейшем был преобразован в весьма неплохой код. Я перешел на Delphi! Да, многие могут сказать, что язык устарел, и не обладает должным функционалам, однако в своей работе я его применяю постоянно. Обучился сему творению благодаря Михаилу Фленову (низкий поклон вам, Миша).
Итак, переходим к финальной версии программы, которая была написана, спустя месяца два – три после моего первого “чудо творения”.
Итак, суть осталось точно такой же, да и шаги не поменялись. Программулиной Wire Shark узнал, какая последовательность отправляется в POST запросе при авторизации. И меня сильно напугал один факт: пароль был зашифрованным.
Небольшое отклонение: логин на сайте представляет собой некоторый набор цифр, а пароль – имя, написанное на русском языке. Однако, в программе Wire Shark на сайт отправлялся шестнадцатеричный код следующего формата: %D0% FF %D0% FF %D1% FF
. Как позже выяснилось, символы “FF” кодировали буквы имени, а %D0%
и %D1%
, что то вроде контрольных байт. З.Ы. Огромная просьба к знатокам, читающим эту статью, если это какой либо общеизвестный сетевой протокол, то не кидайтесь помидорами, а дайте, пожалуйста, ссылку, где можно прочитать про него. Но т.к. я не сталкивался с таким раньше, пришлось разбираться во всем самому.
Первым делом я обратил внимание на повторяющиеся символы %D1%
и %D0%
, которые, как я сразу и предположил, являются контрольными байтами, однако, оставалась загадкой, чем отличается %D0%
от %D1%
. Но это пока отложим, едем дальше. Как же шифруется пароль? А он шифруется достаточно просто, предположим, меня зовут Василий, давайте запишем мое имя в ASCII символах:
82 (В) A0 (а) E1 (с) A8 (и) AB (л) A8 (и) A9 (й)
А на сайт отправляется следующая последовательность:
72 (В) 90 (а) 61 (с) 98 (и) 9B (л) 98 (и) 99 (й)
Хм, просматривается одна зависимость…. А, точно! Если внимательно приглядеться, то у каждого символа, отправляемого на сайт, старший байт уменьшается на 1. Бум! Загадка разгадана.
Хотя, стоп, а почему же тогда вместо E1
(буква с), на сайт отправляется 61? А черт ее знает! Просто запомним, что для символов, лежащих в диапазоне от E0
до EF
из старшего байта необходимо вычитать не 1, а 6. Собственно и все! А помните, я говорил про контрольный символ %D1%
? Так вот, этот символ как раз таки ставится перед символами из данного диапазона. Ну, собственно и все. Далее привожу кусок кода, отвечающий за «шифровку».
Код ""
for i := 1 to length(password) do
begin
temp := Ord(password[i]); //Представили пароль в HEX виде
if (temp < 1088) or (temp > 1103) then // Значения символов E0 и EF
begin //Если вне этого диапазона, то %D0%
pasBytes[i] := '%D0%' + IntToHex(((temp) - 896), 2); // + 128 - 1024 для шифрования
newPassword := newPassword + pasBytes[i];
end
else
begin //Иначе %D1%
pasBytes[i] := '%D1%' + IntToHex(((temp) - 960), 2); // +64 -1024 для шифрования
newPassword := newPassword + pasBytes[i];
end;
end;
//1024 здесь вычитается потому, что в Delphi почему то ASCII символы начинаются с #400
//Почему - не ясно
Финальная последовательность, отправляемая на сайт, будет выглядеть следующим образом:
%D0% 72 %D0% 90 %D1% 61 %D0% 98 %D0% 9B %D0% 98 %D0% 99
Собственно это и была самая сложная часть работы.
Далее, после авторизации, пользователь вставляет в строку ввода ссылку на необходимую книгу. Программа же в это время отправляет Get запрос на сервер, из ответа которого, затем в автоматическом режиме находит название книги, ее ID, и количество страниц. Все эти данные сохраняются в глобальные переменные. И, затем, после нажатия кнопки “Download”, в отдельном потоке отправляются Get запросы на сервер, из которых и забираются картинки с изображениями страниц. Которые в дальнейшем, с помощью библиотеки Synapse формируются в единый PDF файл.
На этом работы программы и заканчивается. К приложению добавлены всякие украшательства, по типу значка и строчки загрузки.
В общем, то и все. Если кому надо, могу выложить исходники на Github и выложить в комментариях ссылку. Также хотелось услышать ваше мнение по поводу моей «дешифровки». Всем спасибо, до скорых встреч на просторах интернета.
Squoworode
Osiris74 Автор
Ну да, изобрел велосипед заново)
Спасибо за ссылку, будет весьма полезной