Bo día.
Despois de rematar de escribir outro script de Bash, decateime de que todo debería ter sido completamente diferente, pero todo funcionou. Quero amosarvos os trucos e trucos feos que escribín para resolver o problema, pero sen moitos coñecementos. Noutras palabras, unha caricatura da programación.
Tarefa
Algo se fixo necesario para:
- Produciu moitas rimas para a palabra, agás os cadrados
- Interseccionou moitas rimas de dúas palabras
Para que? Ben, é necesario, e punto.
Para os que non o saiban, unha rima cadrada (coloquialmente, un cadrado) son dúas palabras que comparten as dúas últimas letras, o que (a miúdo, só) as fai rimar. Por exemplo, rosas - xeadas; pneumático - coche. O uso de cadrados na versificación moderna non é especialmente favorecido pola xente debido á súa primitividade.
decisión
A solución máis sinxela parecíame ser escribir un script Bash usando un xerador de rimas existente, HOST, que selecciona principalmente rimas baseadas na asonancia, non na ortografía. Que é HOST? Porque se uso o nome real do sitio web, dirán que é un anuncio. Por que non seguir usándoo? En primeiro lugar, a pesar da súa vantaxe de seleccionar rimas baseadas na asonancia, aínda a miúdo produce cadrados. En segundo lugar, aínda tes que pensar co teu cerebro, perder tempo cambiando entre pestanas e memorizar palabras repetidas en listas para atopar unha rima para dúas palabras.
Conseguir rimas fortes
Que sei eu? Sei sobre a utilidade. wget, que descarga unha páxina desde un URL especificado. De acordo, executamos a solicitude e obtemos unha páxina HTML nun ficheiro co nome da palabra que rima. Por exemplo, busquemos a palabra "aquí":
wget https://HOST/rifma/здесь Pero só preciso a lista de palabras, como podo eliminar todo o demais? Miramos e vemos que a lista de palabras está formatada, curiosamente, como unha lista, e as palabras están en etiquetas. Ben, temos unha gran utilidade. sed — escribámolo así:
cat $word | grep '<li>' | sed -e "s%<li>%%" | sed -e "s%</li>%%" | sed -e "s/ //g" | sed -e "/^$/d" 1> $wordPrimeiro, selecciona as liñas que conteñen a etiqueta do ficheiro de Word. — obtemos un feixe de etiquetas e cadeas baleiras con palabras. Eliminamos a propia etiqueta e a súa etiqueta de peche; aquí, úsanse signos de porcentaxe en lugar de barras inclinadas porque na propia etiqueta Xa hai unha barra, por que? sed Non te entendo moi ben. Pero as porcentaxes están ben. Elimina todos os espazos do ficheiro e elimina as liñas baleiras. Voilà: unha lista de palabras xa feita.
Para eliminar palabras que riman polas súas últimas letras, seleccionamos as dúas últimas letras da palabra orixinal e limpamos a lista:
squad=${word:((${#word}-2)):2}
cat $word | sed -e "/.$squad$/d" 1> $wordEstamos a buscar, a probalo... todo funciona... Entón, onde está a lista da palabra "xogar"? E da palabra "ir"? O ficheiro está baleiro! Iso débese a que estas palabras son verbos, e sabemos o que lles ocorre ás que riman con verbos. A rima verbal é aínda peor que a rima cadrada, porque o ruso ten máis verbos, e todos teñen as mesmas terminacións, razón pola cal non se incluíron no ficheiro final despois de comprobar as terminacións.
Pero non nos apresuremos. Todas as palabras non só teñen rimas, senón tamén asonancias, que ás veces soan moito mellor que as rimas; así é como se chaman asonancias (francés asonance, do latín assono, que soa afinado).
Obtemos asonancias.
Aquí é onde comeza a diversión: as asonancias aparecen nun URL separado e na mesma páxina, executando un script, enviando unha solicitude HTTP e recibindo unha resposta. Como podo dicir wget"Premer o botón? Pero non hai xeito. Triste."
Ao decatarme de que o URL da liña estaba a cambiar dalgún xeito, copiei o que había alí despois de cambiar a asonancia e pegueino nunha nova lapela do navegador: abríronse rimas fortes. Iso non.
De feito, pensei, para servidor Non debería importar se o script que lle envía a solicitude se executa ou se a persoa a escribe manualmente. Non si? Quen sabe? Imos comprobalo.
Onde enviar? Que enviar? Unha solicitude HTTP ao IP do servidor, algo como GET... despois algo HTTP/1.1... Necesitamos ver que está a enviar o navegador e onde. Instalémolo. wireshark, vexamos o tráfico:
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Ó.
Hm... que? Ah si, temos HTTPS. Que deberiamos facer? Lanzar un ataque MITM contra nós mesmos? Idealmente, a vítima cooperaría.
Entón, despois de descubrir como navegar polo navegador, finalmente atopei a propia solicitude e o destinatario. Comecemos:
Diálogo co terminal
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.Je. Je, je. De verdade, que esperaba cando enviei unha solicitude HTTP simple a un porto HTTPS? Debería cifrala agora? Todo ese alboroto coas claves RSA e despois con SHA256. Para que molestarse? Está aí. OpenSSL Para estes casos. Ben, xa sabemos que facer, pero primeiro eliminemos os campos Referente e Cookie; non creo que fagan moita diferenza:
Diálogo co terminal
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

Trátase dalgún tipo de palabrota do servidor? Ben, polo menos recibín unha resposta de 200 °C, polo que as cookies e o referente non afectan a nada. Está comprimido con gzip, pero ao copiar copia os caracteres ASCII. Certo, podes eliminar a liña. Codificación de aceptaciónTodo está ben: obtemos un documento HTML, agora con asonancias. Pero aquí hai dúas preguntas: como executamos OpenSSL e lle enviamos datos a través dun script? E como lemos a saída se, despois de recibir a resposta, quedamos nun "shell" de OpenSSL? Pódese facer algo con respecto a isto último, pero co primeiro...
É tan bo que haxa Habr, onde lin sobre a utilidade esperar, que automatiza o proceso de interacción con programas que requiren interacción humana. Aínda máis atractiva é a presenza dun equipo espera automática, xerando esperar un script baseado nas túas accións. Ben, imos lanzalo, facer todo isto e aquí está o script rematado. Pero é realmente enorme, e iso é porque OpenSSL mostra certificados, claves e esperar Agarda a que todo isto saia á saída. Necesitamos isto? Non. Eliminamos toda a primeira solicitude, deixando só o último salto de liña 'r'. Tamén eliminamos os campos User-Agent e Accept da nosa solicitude; non afectan a nada. De acordo, executémolo. O script execútase, pero onde está o valioso documento HTML? Espere comeuno. Para que o cuspa, tes que poñer:
set results $expect_out(buffer)antes do final do script: así é como se escribirá a saída do executable esperarComando 'om e móstrase na pantalla. O resultado terá un aspecto semellante a este:
Agardar guión
#!/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 eofPero iso non é todo! Como xa te decataches, o URL da solicitude era estático en todos os exemplos, pero é o que determina para que palabra se mostrarán as asonancias. Polo tanto, resulta que sempre buscaremos a palabra "%d0%b7%d0%b4%d0%b5%d1%81%d1%8c" en ASCII ou "aquí" en UTF-8. Que deberiamos facer? Por suposto, simplemente xerar un novo script cada vez! Pero xa non. espera automática'om, pero coa axuda de perder, porque na nova versión, nada cambia agás a palabra. E longa vida ao novo problema: como podemos traducir de forma intelixente unha palabra do cirílico ao formato URL? Tampouco hai nada especial para o terminal. Ben, podemos facelo, non si? Podemos:
Mira o que podo facer!
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')}Entón, temos un script que converte unha palabra en texto ASCII, que logo xera outro script que solicita unha páxina web con asonancias desde o servidor a través de OpenSSL. Despois rediriximos a saída do último script a un ficheiro e executámolo á antiga usanza. exceso, cadrados e escribir no ficheiro.
Intersección de conxuntos. Resumo
Isto é o que causa menos problemas. Realizamos os procedementos anteriores para dúas palabras, logo comparamos cada palabra das dúas listas coa outra e, se atopamos unha coincidencia, a mostramos. Agora temos un script que toma dúas palabras como entrada e mostra unha lista de palabras que riman con ambas, tendo en conta a asonancia, e todo isto sen cambiar manualmente entre catro pestanas nin memorizar palabras "a ollo": todo se recolle, contabiliza e descártase automaticamente. Excelente.
O propósito desta publicación era demostrar que se alguén quere algo, farao pase o que pase. É moi ineficaz, tortuoso e terrorífico, pero funcionará.
Fonte: www.habr.com
