Milleks on arvutimaailma õppiva õpilase aju võimeline?

Tere päevast.

Olles lõpetanud Bashis järjekordse stsenaariumi kirjutamise, mõistsin, et kõik peaks olema täiesti erinev, kuid kõik töötas. Ma tahan teile näidata, milliseid roppusi ja karkusid ma probleemi lahendamiseks kirjutasin, kuid omamata veel teadmistevankrit. Ehk siis programmeerimise karikatuur.

Ülesanne


Midagi oli vaja, et:

  • Kuvas sõna jaoks palju riime, välja arvatud ruudud
  • Ristis palju kahe sõna riime

Milleks? Noh, see on kõik – ja kõik.
Kes ei tea, siis ruutriim (tavalises kõnepruugis ruut) on kaks sõna, mille kaks viimast tähte õigekirjas langevad kokku, mis (sageli on see ainus asi) muudab need riimiks. Näiteks roosid on härmas; rehv - auto. Ruudude kasutamine tänapäevases versifikatsioonis pole nende primitiivsuse tõttu inimeste poolt eriti heaks kiidetud.

otsus


Mulle tundus, et kõige lihtsam lahendus on kirjutada Bashis skript, mis kasutab juba olemasolevat riimigeneraatorit - HOST, mis valib need peamiselt kaashääliku, mitte õigekirja järgi. Missugune HOST? Sest kui märgite saidi tegeliku nime, öeldakse, et see on reklaam. Miks mitte jätkata selle kasutamist? Esiteks, hoolimata eelistest valida riime kaashäälikute põhjal, toodab ta endiselt sageli ruute. Teiseks tuleb kahe sõna jaoks riimi leidmiseks ikkagi mõelda ajuga, kulutada aega vahekaartide vahel vahetamisele ja energiat loendites korduvate sõnade meeldejätmiseks.

Tugevate riimide saamine

Mida ma tean? Ma tean utiliidi kohta wget, mis laadib määratud URL-i lehe alla. Olgu, täidame päringu – saame HTML-lehe failis, mille nimi on riimuva sõnaga. Näiteks otsime sõna "siin":

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

Aga mul on vaja ainult sõnade loetelu, kuidas ma saan kõigest muust lahti? Vaatame ja näeme, et sõnade loend on vormindatud, ükskõik kui kummaline see ka poleks, loendi kujul ja sõnad on siltides . Noh, meil on suurepärane kasulikkus. janu - paneme selle kirja järgmiselt:

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

Kõigepealt valige Wordi failist read, mis sisaldavad silti — saame hunniku tühje silte ja sõnadega ridu. Eemaldame sildi enda ja selle sulgemise – siin kasutatakse kaldkriipsude asemel protsendisümboleid, kuna sildis endas seal on juba kaldkriips, miks? janu ei saa sinust natuke aru. Ja intressidega on kõik korras. Eemaldame failist kõik tühikud, eemaldame tühjad read. Voila - valmis sõnade loend.

Viimaste tähtedega riimuvate sõnade eemaldamiseks valige algsõnast kaks viimast tähte ja tühjendage loend:

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

Vaatame, proovime - kõik toimib... kus on sõna “mängima” loetelu? Ja sõna "ma lähen" jaoks? Fail on tühi! Ja see kõik on sellepärast, et need sõnad on tegusõnad ja me teame, mida nad teevad nendega, kes verbidega riimuvad. Teguriim on hullem kui isegi ruutriim, sest vene keeles on verbe kõige rohkem ja neil kõigil on ühesugused lõpud, mistõttu neid pärast lõppude kontrollimist lõppfailis ei olnud.

Meil aga pole kiiret. Iga sõna jaoks pole mitte ainult riime, vaid ka assonansse, mis mõnikord kõlavad palju paremini kui riim - sellepärast on need assonantsid (prantsuse assonants, ladina keelest assono - ma kõlan harmoonias).

Saame assonantsid

Siit algab lõbu: assonantsid ilmuvad eraldi URL-ile ja samal lehel, käivitades skripti, saates HTTP päringu ja saades vastuse. Kuidas seda öelda wget'Kas sa vajutad nuppu? Aga mitte kuidagi. Kurb küll.

Märgates, et rea URL on kuidagi muutumas, kopeerisin pärast assonantsidele üleminekut seal oleva ja kleepisin selle uude brauseri vahelehele – avanesid tugevad riimid. Mitte, et.

Põhimõtteliselt arvasin ma, et serveri jaoks ei tohiks olla vahet, kas talle päringu saatnud skript täidetakse või kas inimene tipib selle käsitsi. Nii et? Kes teab, lähme vaatame üle.

Kuhu saata? Mida saata? HTTP päring serveri IP-le, seal on midagi nagu GET... siis on midagi HTTP/1.1... Peame vaatama, mida brauser saadab ja kuhu. Installige wireshark, vaadake liiklust:

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Ó.

Ee... mida? Oh jah, meil on HTTPS. Mida teha? Kas käivitada enda vastu MITM-rünnak? Ideaalis aitab meid ohver ise.

Üldiselt, olles otsustanud brauseris surfata, leidsin lõpuks päringu enda ja adressaadi. Mine:

Dialoog terminaliga

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.

Tere. Hehehe. Tõepoolest, seda ma ootasin, kui saadan HTTPS-i porti tühja HTTP-päringu. Kas me peaksime nüüd krüpteerima? Kogu see askeldamine RSA-klahvidega ja seejärel SHA256-ga. Miks, on OpenSSL selliste asjade eest. Noh, me juba teame, mida teha, lihtsalt eemaldame kõigepealt väljad Referer ja Cookie – ma arvan, et need ei mõjuta asja palju:

Dialoog terminaliga

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

Milleks on arvutimaailma õppiva õpilase aju võimeline?

Mis see on, serverisse vandumine? Vähemalt vastasid nad mulle 200 OK, mis tähendab, et küpsised ja suunaja ei mõjuta midagi. Tihendus on gzip, kuid kopeerimisel kopeeritakse ASCII märgid. Täpselt, saate joone eemaldada Nõustu-kodeering. Kõik on korras – saame HTML-dokumendi, nüüd koos assonantsidega. Siin on aga kaks küsimust: kuidas OpenSSL-i käivitada ja skripti abil sinna andmeid edastada? Ja kuidas lugeda väljundit, kui pärast vastuse saamist jääme justkui OpenSSL-i kesta? Kui suudad teisega midagi välja mõelda, aga esimesega...

Hea, et on Habrkust ma utiliidi kohta lugesin ootama, mis automatiseerib inimeste suhtlemist eeldavate programmidega suhtlemise protsessi. Meeskonna olemasolu on veelgi atraktiivsem automaatne ootus, genereerimine ootama skript, mis põhineb teie tegevusel. Noh, käivitame selle, teeme seda kõike ja siin on valmis skript. Ainult ta on väga suur ja kõik sellepärast OpenSSL kuvab sertifikaadid, võtmed ja ootama ootab kõige selle väljundit. Kas me vajame seda? Ei. Eemaldame kogu esimese viipa, jättes alles ainult viimase reavahetuse "r". Samuti eemaldame oma taotlusest väljad User-Agent ja Accept – need ei mõjuta midagi. Niisiis, käivitame. Skript käivitati, kuid kus on hinnatud HTML-dokument? Ootama sõi ära. Et ta selle välja sülitaks, peate panema:

set results $expect_out(buffer)

enne skripti lõppu – nii kirjutatakse käivitatava faili väljund ootama'om käsk ja kuvatakse ekraanil. Kokkuvõttes midagi sellist:

oodake skripti

#!/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

Kuid see pole veel kõik! Nagu näete, oli päringu URL kõigis näidetes staatiline, kuid URL on see, mis vastutab selle eest, milline sõna assonantsidega seostatakse. Ja nii selgub, et otsime pidevalt ASCII-s sõna “%d0%b7%d0%b4%d0%b5%d1%81%d1%8c” või UTF-8-s “siin”. Mida teha? Muidugi looge lihtsalt iga kord uus skript, sõbrad! Enam mitte automaatne ootus'oh, ja abiga miss, sest Meie uues ei muutu midagi peale sõna. Ja elagu uus probleem: kuidas me saame arukalt tõlkida sõna kirillitsast URL-i vormingusse? Ka terminalis pole midagi erilist. Noh, pole midagi, saame hakkama, eks? Saab:

Vaata, mida ma teha saan!

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')}

Kokku on meil skript, mis teisendab sõna ASCII tekstiks, genereerides teise skripti, mis nõuab serverilt OpenSSL-i kaudu assonantsidega saidilehte. Ja siis suuname viimase skripti väljundi faili ja edastame selle vanaviisi läbi "filtrid" lisaruudud ja kirjutage need faili.

Paljude ristmik. Alumine joon

Tegelikult põhjustab see kõige vähem probleeme. Teeme ülaltoodud toimingud kahe sõna jaoks, seejärel võrdleme kahest loendist iga sõna mõlemaga ja kui leitakse vaste, väljastame selle. Nüüd on meil skript, mis võtab sisendiks kaks sõna ja kuvab loendi sõnadest, mis riimuvad mõlemaga, võttes isegi assonantse arvesse ning seda kõike ilma käsitsi nelja vahelehe vahel vahetamata ja sõnu "silma järgi" meelde jätmata – kõik kogutakse, arvestatakse jaoks ja visatakse automaatselt ära. Imeline.

Selle väljaande eesmärk oli näidata, et kui inimesel on midagi vaja, siis ta teeb seda niikuinii. Väga ebaefektiivne, kõver, jube, kuid see töötab.

Allikas: www.habr.com

Lisa kommentaar