На какво е способен мозъкът на ученик, изучаващ компютърния свят?

Добър ден.

След като приключих с писането на друг скрипт в Bash, разбрах, че всичко трябва да е напълно различно, но всичко работи. Искам да ви покажа какви безобразия и патерици написах, за да реша проблема, но все още нямам вагон знания. С други думи, карикатура на програмирането.

Задача


Нещо стана необходимо за:

  • Показани много рими за думата, с изключение на квадратите
  • Пресече множеството рими на две думи

За какво? Е, това е - и това е.
Кой не знае, квадратна рима (на общ език - квадрат) са две думи, чиито последни две букви в правописа съвпадат, което (често това е единственото) ги прави рима. Например, розите са мразовити; гума - автомобил. Използването на квадрати в съвременната версификация не е особено одобрено от хората поради тяхната примитивност.

Решение


Струваше ми се, че най-простото решение е да напиша скрипт в Bash, който използва вече съществуващ генератор на рими - HOST, който ги избира предимно по съзвучие, а не по правопис. Какъв HOST? Защото ако посочиш истинското име на сайта, ще кажат, че е реклама. Защо не продължите да го използвате? Първо, въпреки предимството си да избира рими въз основа на съзвучия, той все още често произвежда квадрати. Второ, все още трябва да мислите с мозъка си, да прекарвате време в превключване между раздели и енергия в запаметяване на повтарящи се думи в списъци, за да намерите рима за две думи.

Получаване на силни рими

Какво знам? Знам за помощната програма Wget, който изтегля страницата на посочения URL адрес. Добре, нека изпълним заявката - получаваме HTML страница във файл, наречен с римувана дума. Например, нека потърсим думата „тук“:

wget https://HOST/rifma/здесь

Но имам нужда само от списък с думи, как мога да се отърва от всичко останало? Поглеждаме и виждаме, че списъкът с думи е форматиран, колкото и странно да е, под формата на списък, а думите са в тагове . Е, имаме страхотна полезност. жажда - нека го запишем така:

cat $word | grep '<li>' | sed -e "s%<li>%%" | sed -e "s%</li>%%" | sed -e "s/ //g" | sed -e "/^$/d" 1> $word

Първо, от word файла изберете редовете, които съдържат етикета — получаваме куп празни тагове и редове с думи. Премахваме самия таг и затварящия му - тук се използват символи за процент вместо наклонени черти, защото в самия таг вече има наклонена черта, защо? жажда малко не те разбира. И всичко е наред с лихвата. Премахваме всички интервали от файла, премахваме празните редове. Voila - готов списък с думи.

За да премахнете думи, които се римуват с последните букви, изберете последните две букви от оригиналната дума и изчистете списъка:

squad=${word:((${#word}-2)):2}
cat $word | sed -e "/.$squad$/d" 1> $word

Гледаме, опитваме - всичко работи... така че къде е списъкът за думата "игра"? А за думата „отивам“? Файлът е празен! И това е всичко, защото тези думи са глаголи и знаем какво правят с тези, които се римуват с глаголи. Глаголната рима е по-лоша дори от квадратната рима, защото руският език има най-много глаголи и всички те имат еднакви окончания, поради което не бяха в крайния файл след проверка на окончанията.

Ние обаче не бързаме. За всяка дума има не само рими, но и асонанси, които понякога звучат много по-добре от римата - затова са асонанси (фр. assonance, от лат. assono - звуча в тон).

Получаваме асонанси

Тук започва забавлението: асонансите се появяват на отделен URL адрес и на същата страница чрез изпълнение на скрипт, изпращане на HTTP заявка и получаване на отговор. Как да кажа Wget„Натискаш ли бутона? Но няма начин. за съжаление

Забелязвайки, че URL адресът в реда по някакъв начин се променя, копирах това, което беше там след превключване към асонанси, и го поставих в нов раздел на браузъра - отвориха се силни рими. Не това.

По същество си помислих, че за сървъра не би трябвало да има значение дали скриптът, който му изпраща заявката, се изпълнява или дали човекът я въвежда на ръка. Така? Кой знае, нека отидем да го проверим.

Къде да пратя? Какво да изпратя? HTTP заявка към IP на сървъра, има нещо като GET... след това има нещо HTTP/1.1... Трябва да видим какво изпраща браузърът и къде. Инсталирай Wireshark, вижте трафика:

0040 37 5d a3 84 27 e7 fb 13 6d 93 ed cd 56 04 9d 82 7]£.'çû.m.íÍV...
0050 32 7c fb 67 46 71 dd 36 4d 42 3d f3 62 1b e0 ad 2|ûgFqÝ6MB=ób.à.
0060 ef 87 be 05 6a f9 e1 01 41 fc 25 5b c0 77 d3 94 ï.¾.jùá.Aü%[ÀwÓ.

Хм... какво? О, да, имаме HTTPS. Какво да правя? Да предприемете MITM атака срещу себе си? В идеалния случай самата жертва ще ни помогне.

Като цяло, след като реших да сърфирам в браузъра, най-накрая намерих самата заявка и адресата. Отивам:

Диалог с терминала

telnet IP PORT
Trying IP...
Connected to IP.
Escape character is '^]'.
GET /rifma/%D0%BC%D0%B0%D1%82%D1%8C?mode=block&type=asn HTTP/1.1
Host: HOST
Accept-Language: en-US,en;q=0.5
X-Requested-With: XMLHttpRequest
Connection: close

HTTP/1.1 400 Bad Request
Server: nginx/1.8.0
Date: Sun, 03 Nov 2019 20:06:59 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 270
Connection: close

<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.8.0</center>
</body>
</html>
Connection closed by foreign host.

Хей. хехехе Наистина, това очаквах, когато изпращам чиста HTTP заявка към HTTPS порт. Трябва ли да криптираме сега? Цялата тази суматоха с RSA ключове, след това с SHA256. Защо, има OpenSSL за такива неща. Е, вече знаем какво да правим, само първо ще премахнем полетата Referer и Cookie - мисля, че те няма да повлияят много на въпроса:

Диалог с терминала

openssl s_client -connect IP:PORT
{Всякие ключи, сертификаты}
GET /rifma/%D0%B7%D0%B4%D0%B5%D1%81%D1%8C?mode=block&type=asn HTTP/1.1
Host: HOST
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/javascript,text/html,application/xml,text/xml,*/*
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
Connection: keep-alive

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Status: 200 OK
Date: Sun, 03 Nov 2019 20:34:33 GMT
Set-Cookie: COOKIE
X-Powered-By: Phusion Passenger 5.0.16
Server: nginx/1.8.0 + Phusion Passenger 5.0.16
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Cache-Control: no-cache
Strict-Transport-Security: max-age=31536000
Content-Security-Policy: block-all-mixed-content
Content-Encoding: gzip

На какво е способен мозъкът на ученик, изучаващ компютърния свят?

Какво е това, псувни на сървъра? Поне на мен ми отговориха 200 ОК, което означава че бисквитките и реферера не влияят на нищо. Компресията е gzip, но при копиране се копират ASCII символи. Точно така, можете да премахнете линията Приемане-кодиране. Всичко е наред - получаваме HTML документ, вече с асонанси. Но ето два въпроса: как да стартирам OpenSSL и да прехвърлям данни към него с помощта на скрипт? И как да прочетем изхода, ако след получаване на отговора оставаме, така да се каже, в OpenSSL „обвивка“? Ако можете да измислите нещо с второто, но с първото...

Добре че има Хабркъдето прочетох за помощната програма очаквам, който автоматизира процеса на взаимодействие с програми, които очакват човешко взаимодействие. Да имаш екип е още по-привлекателно автоматично очакване, генериране очаквам скрипт въз основа на вашите действия. Е, стартираме го, правим всичко това и ето го готовият скрипт. Само той е много огромен и всичко това, защото OpenSSL показва сертификати, ключове и очаквам очаква резултата от всичко това. имаме ли нужда от това Не. Премахваме целия първи промпт, оставяйки само последния прекъсващ ред 'r'. Също така премахваме полетата User-Agent и Accept от нашата заявка - те не засягат нищо. И така, нека стартираме. Скриптът беше изпълнен, но къде е ценният HTML документ? Очаквам изяде го. За да го накарате да го изплюе, трябва да поставите:

set results $expect_out(buffer)

преди края на скрипта - така ще бъде написан изходът на изпълнимия файл очаквам'om команда и се показва на екрана. Накратко, нещо подобно:

очаквам скрипт

#!/usr/bin/expect -f

set timeout -1
spawn openssl s_client -connect IP:PORT
match_max 100000
expect -exact "
---r
"
send -- "GET /rifma/%d0%b7%d0%b4%d0%b5%d1%81%d1%8c?mode=block&type=asn HTTP/1.1rHost: HOSTrAccept-Language: en-US,en;q=0.5rX-Requested-With: XMLHttpRequestrConnection: close"
expect -exact "GET /rifma/%d0%b7%d0%b4%d0%b5%d1%81%d1%8c?mode=block&type=asn HTTP/1.1r
Host: HOSTr
Accept-Language: en-US,en;q=0.5r
X-Requested-With: XMLHttpRequestr
Connection: close"
send -- "r"
set results $expect_out(buffer)
expect -exact "r
"
send -- "r"
expect eof

Но това не е всичко! Както можете да видите, във всички примери URL адресът на заявката е статичен, но URL адресът е отговорен за това коя дума ще бъде свързана с асонанси. И така се оказва, че постоянно ще търсим думата „%d0%b7%d0%b4%d0%b5%d1%81%d1%8c“ в ASCII или „тук“ в UTF-8. Какво да правя? Разбира се, просто генерирайте нов скрипт всеки път, приятели! Вече не автоматично очакване„О, и с помощта ехо, защото В нашия нов нищо не се променя освен думата. И да живее новият проблем: как можем интелигентно да преведем дума от кирилица в URL формат? За терминала също няма нищо особено. Е, всичко е наред, можем да го направим, нали? Мога:

Вижте какво мога да направя!

function furl {
furl=$(echo "$word" | sed 's:А:%d0%90:g;s:Б:%d0%91:g;s:В:%d0%92:g;s:Г:%d0%93:g;s:Д:%d0%94:g;s:Е:%d0%95:g;s:Ж:%d0%96:g;s:З:%d0%97:g;s:И:%d0%98:g;s:Й:%d0%99:g;s:К:%d0%9a:g;s:Л:%d0%9b:g;s:М:%d0%9c:g;s:Н:%d0%9d:g;s:О:%d0%9e:g;s:П:%d0%9f:g;s:Р:%d0%a0:g;s:С:%d0%a1:g;s:Т:%d0%a2:g;s:У:%d0%a3:g;s:Ф:%d0%a4:g;s:Х:%d0%a5:g;s:Ц:%d0%a6:g;s:Ч:%d0%a7:g;s:Ш:%d0%a8:g;s:Щ:%d0%a9:g;s:Ъ:%d0%aa:g;s:Ы:%d0%ab:g;s:Ь:%d0%ac:g;s:Э:%d0%ad:g;s:Ю:%d0%ae:g;s:Я:%d0%af:g;s:а:%d0%b0:g;s:б:%d0%b1:g;s:в:%d0%b2:g;s:г:%d0%b3:g;s:д:%d0%b4:g;s:е:%d0%b5:g;s:ж:%d0%b6:g;s:з:%d0%b7:g;s:и:%d0%b8:g;s:й:%d0%b9:g;s:к:%d0%ba:g;s:л:%d0%bb:g;s:м:%d0%bc:g;s:н:%d0%bd:g;s:о:%d0%be:g;s:п:%d0%bf:g;s:р:%d1%80:g;s:с:%d1%81:g;s:т:%d1%82:g;s:у:%d1%83:g;s:ф:%d1%84:g;s:х:%d1%85:g;s:ц:%d1%86:g;s:ч:%d1%87:g;s:ш:%d1%88:g;s:щ:%d1%89:g;s:ъ:%d1%8a:g;s:ы:%d1%8b:g;s:ь:%d1%8c:g;s:э:%d1%8d:g;s:ю:%d1%8e:g;s:я:%d1%8f:g;s:ё:%d1%91:g;s:Ё:%d0%81:g')}

Като цяло имаме скрипт, който преобразува дума в ASCII текст, генерирайки друг скрипт, който изисква страница на сайта с асонанси от сървъра чрез OpenSSL. След това пренасочваме изхода на последния скрипт към файл и по старомодния начин го предаваме "филтри" допълнителни квадратчета и ги запишете във файла.

Пресечна точка на много. Долен ред

Всъщност точно това създава най-малко проблеми. Извършваме горните процедури за две думи, след което от двата списъка сравняваме всяка дума с всяка и ако се намери съвпадение, го извеждаме. Сега имаме скрипт, който приема две думи като вход и показва списък с думи, които се римуват и с двете, и дори вземайки предвид асонансите, и всичко това без ръчно превключване между четири раздела и запомняне на думите „на око“ - всички събрани, отчетени за и се изхвърля автоматично. Чудесен.

Целта на тази публикация беше да покаже, че ако човек има нужда от нещо, той все пак ще го направи. Много неефективно, криво, страховито, но ще работи.

Източник: www.habr.com

Добавяне на нов коментар