Category Archives: Perl

Sulla steganografia

Immagino che siate in trepidante attesa del seguito di Macchine a stati finiti e pattern matching, o dovete ancora digerire quel malloppo… tranquilli, perché devo trovare il tempo di impegnarmi a scriverlo (suspense…) e su due piedi non mi viene.

Quindi, nel frattempo…

flowersex

Scavo un po’ questo blog e trovo Due immagini identiche non proprio uguali…. A me la steganografia è sempre piaciuta un sacco; purtroppo quando se ne parla popolarmente spesso e volentieri si fa confusione e si dicono sciocchezze. E poi si fa sempre e solo il classico esempio di “qualcosa” nascosto dentro un’immagine.

Ma perché un’immagine? Forse perché è qualcosa di più “spendibile” in un film o in un racconto? Fa più scena, insomma. Come Nella morsa del ragno.

In quel mio articolo racconto la storiella del «greco [che] scrisse un messaggio sulla testa rasata di un suo schiavo, aspettò che gli crescessero i capelli e gli ordino di recarsi nella città del suo amico destinatario», solo che la ricordavo diversa. Ma il succo è lo stesso ed è ciò che conta.

Qualche giochetto steganografico e molte altre cose si possono apprendere anche da qui. È un gioco e se vi va di giocare non ve ne pentirete. Tanto per capirci (forse), dietro c’è Davide Eynard; parliamo di pezzettini di certa storia. E a proposito, Lore updated 6 years, 5 months and 6 days ago, dice… questo mi mette un po’ di nostalgia (perché 8 anni fa ero più giovane e pensavo che quel sito mi avrebbe fornito materiale nuovo fino all’eternità).

Torniamo in tema: sempre se la memoria non mi tradisce, è lì (giocando su 3564020356) che appresi e la storiella e del libro di Trithemius sulla steganografia… È anche su archive.org. Dovete ripassare un po’ di latino (ma non è il latino di Cicerone, si legge un po’ più facilmente… ehm). Trovate anche cose come Solved: The Ciphers in Book iii of Trithemius’s Steganographia. Sempre per capirci, Trithemius è l’autore di Polygraphia, «the first printed book on cryptography» (lo trovate scansionato su Books Google, se vi interessa).

polytrit

Naturalmente non poteva non parlarne pure l’NSA, che ci dà anche altri titoli che val la pena leggere nelle fredde serate infernali.

Steganografare

Dicevamo appunto che la steganografia non deve per forza nascondere “qualcosa” in un’immagine, come dimostra la storia del greco.

Oh,     tremenda    tormenta     /
che  mi   bloccò sul     monte!    /
Così  forte    il  vento che    pure /
Harry   Potter, con      gli incantesimi     /
e   le     pozioni  e    /
i   suoi amici   e   la   sua     fortuna,   /
poteva rimanerci secco!    /
Ancora  non capisco    come   riuscii    a   resistere, /
né      donde  venissero  /
i soccorsi     tanto   sperati,      /
che   mi   presero per     i    capelli!  /
Ora    posso      dire d'esser     vivo!   /

Banale ma rende l’idea (o no?). Il seguente programmino può codificare un testo in un testo usando gli spazi. Scusate se ho usato il Perl ma, nonostante sia arrugginito, lo trovo sempre più pratico per fare al volo certe cose!

use strict;
my @frags = ();
my @msg = grep /[A-Z]/, split('',$ARGV[0]);
foreach my $c (@msg) {
    my $a = ord($c) - ord("A");
    push @frags, ($a & 0x1C) >> 2;
    push @frags, ($a & 0x03);
}
my @lines = ();
while (<STDIN>) {
    my @w = split /\s+/;
    my $s = "";
    foreach my $l (@w) {
        my $n;
        if (@frags > 0) {
            $n = shift @frags;
        } else {
            $n = 0;
        }
        $s .= $l . (" "x($n+1));
    }
    print $s . "/\n";
}
print STDERR "left: ".@frags."\n" if @frags>0;

Ora a voi sta scrivere il programma di decodifica (poi lo farò pure io per verificare di aver scritto bene quello di codifica:-D…) Dunque c’è la poesia, che non è il messaggio, ma il messaggio non è nemmeno «occheipanico»… c’è ancora un altro livello. E se ce ne fosse un altro ancora (a parte quello allegorico, che avrete notato…)? …

A proposito… il programmino lo potete usare così:

perl encospace.pl "TESTO" <contenitore.txt

(potete usare solo le lettere maiuscole).

trituso

Annunci

Python vs. Perl

Programming-republic-of-perlSono in ritardo su tutto; devo ancora finire due cose per domani ma devo proprio dire una cosa. Anche perché riguarda in qualche misura quello che devo fare per domani.
Perl, devo essere stato uno dei primi a affrontarlo, è nato nel 1987, controllato anche sulla Wiki, non è un errore, credevo prima. No, non ho prove, anche i libri non li ho più. OK, nostalgia mode OFF 😯

Oggi ho trovato questo post: The Fall Of Perl, The Web’s Most Promising Language.
L’autore, Conor Myhrvold, è –come dire– eclettico. Ma conosce bene la materia il post è informato e esaustivo.

camelMa il motivo vero di queste note è un altro, anzi più di uno.

Python
Oggi le cose in cui Perl eccelleva si fanno con Python; anche le espressioni regolari. E Python ha un grosso vantaggio: la sintassi è molto più amichevole, sembra il Basic di una volta. E anche la storia dell’indentazione (non è che devo dire rientri, vero?) ho visto che è facile da digerire. E Python è molto usato, ci sono librerie (OK, non si chiamano così ma sono quello che una volta si sarebbero chiamate librerie). Metti in conto che non devi compilare e anzi puoi modificare al volo lo script e Python vince alla grande, ad esclusione dei progetti più impegnativi dove si usa Java o il C++. A proposito non so se è una cosa locale ma il C++ ha fama di essere ostico e impegnativo; io trovo tale anche Java, ma chissà 😳

Octave (Matlab)
Conor dice che Python “even expanding at Matlab’s expense“. Però, per quel che ne so, Matlab è usato parecchio per calcoli di matrici e roba simile; e ha gli stessi vantaggi di scripting di Python. Resta da verificare se serva la versione proprietaria o sia sufficiente Octave, FOSS.

awk
Ci sono però dei casi in cui forse Python ha dei rivali. Per esempio gli script di awk di cui ho parlato nei post precedenti. Funzionano, anzi cresceranno in futuro. Anche se c’è il problema di Windows.

OK, a proposito per domani devo vedere se usare awk (o Perl) o Python. Scelta difficile io sono pythonista convinto ma vengo da sh, sed, awk e Perl.
E una delle cose di cui vado orgoglioso tra quelle recenti è fatta con Gnuplot 🙄

Espressioni regolari in Perl

Il mio primo messaggio 🙂

Ciao a tutti!
Per questo mio primo messaggio su questo blog (grazie mille per l’ospitalità) vi parlerò di espressioni regolari in Perl, ma non fatevi prendere dal panico (altrimenti sarò io a farlo…).

Espressioni regolari

Una definizione intuitiva di espressione regolare

Immaginiamo un file di testo come una serie di porte con serrature corrispondenti ad una qualsiasi sequenza dei suoi caratteri. Se per esempio il testo è ‘Casa dolce casa’ la chiave ‘dolce’ aprirà una porta sola ma la chiave ‘asa’ ne aprirà due, una presente nella prima parola ed una nella terza.

L’espressione regolare non è altro che un modo per generare chiavi da provare sul testo e quando una porta si apre possiamo fare sostanzialmente due cose:
* prendere atto che la chiave ha funzionato (come accade quando si vuol validare un indirizzo di posta elettronica);
* oppure se la chiave ha funzionato possiamo voler manipolare il testo (come accade quando si sostituisce una parola con un’altra).

L’utilità delle espressioni regolari sta nel fatto che con esse possiamo generare chiavi anche molto sofisticate in modo semplice ed essenziale: basta scrivere la giusta sequenza di caratteri criptici… 🙂

Come sperimentare?

Il linguaggio Perl è stato progettato per essere un potente strumento per modificare il testo ed è quindi naturale che disponga di una potente libreria per le espressioni regolari (dette anche RegExpr o RegExp oppure ancora RE), ed è anche facilmente reperibile su moltissimi sistemi operativi compreso Windows ed ovviamente Linux e Mac OS X dove lo troveremo già installato (date il comando perl -v per constatarlo).

Se siete poco pratici della riga di comando consiglio di leggere una buona (spero) guida, essenziale nel darvi i concetti di base come per esempio la Guida Tematica alla riga di comando scaricabile liberamente dal sito del GuIT e contenente ulteriori esempi di correzione massiva del testo.

Invece, l’ottimo tutorial PerlReQuick della documentazione ufficiale di Perl vi fornirà con molta chiarezza le informazioni di base sulle espressioni regolari.

La modalità con cui useremo Perl non sarà quella di scrivere codice in uno script ma quella più semplice di digitare un comando al terminale che eseguirà operazioni di sostituzione su molti file di testo in una volta, in una forma estremamente compatta ed immediata.
Il comando avrà la seguente struttura:

$ perl <opzioni> <regexp> <file> <file> ...

Primo esempio: di città in città

Prima di tutto consiglio vivamente di fare gli esperimenti su una copia dei file originali fino a che non si è sicuri di intervenire correttamente sul testo.

La sostituzione si scrive nella forma ‘s/regexp/nuovo testo/’: il carattere iniziale s sta per string ed è obbligatorio poi, separati da caratteri slash, ci sono due campi: il primo è l’espressione regolare, la chiave che verrà provata nelle porte del testo, il secondo è il nuovo testo di sostituzione.
Immaginiamo che nel testo contenuto nel file ‘city.txt’ devono essere sostituite tutte le occorrenze della parola ‘Savona’ con ‘Genova’. Il comando Perl è questo:

$ perl -i -p -e 's/Savona/Genova/g' city.txt

Se osserviamo il formato dell’espressione regolare ci accorgiamo che il primo campo è semplicemente la sequenza dei caratteri da sostituire, poi, che è comparso un nuovo carattere non previsto in coda all’espressione: la g. Si tratta di un modificatore che sta per global ed assicura che tutte le occorrenze trovate e non solo la prima vengano sostituite.
L’opzione al comando -i (inline) dice al compilatore perl di modificare i file sovrascrivendo gli originali. Per rimediare ad eventuali errori l’unico modo è fare una copia di backup dei file e per comodità possiamo farla fare al comando stesso specificando un suffisso all’opzione inline: -ibak oppure -i.bak.
L’opzione -p processa il file con un ciclo (il testo può passare al comando per singole linee) e l’opzione -e (esegui) indica che il codice da eseguire è quello che seguirà subito dopo.

E se per caso abbiamo scritto ‘savona’ anziché ‘Savona’ cosa succede? Semplice, la chiave non gira e ci perderemo quella sostituzione.
Se vogliamo che la chiave giri per entrambe allora o aggiungiamo in coda un ulteriore modificatore i (ignore case):

$ perl -i -p -e 's/Savona/Genova/gi' city.txt

oppure cambiamo l’espressione regolare usando le classi di caratteri definite con parentesi quadre:

$ perl -i -p -e 's/[Ss]avona/Genova/g' city.txt

Ed ancora, se dobbiamo sostituire la città ‘Sestri Levante’ con ‘Imperia’ come cavarsela con gli spazi? Niente panico, se è possibile che tra ‘Sestri’ e ‘Levante’ ci sia un carattere spazio, o addirittura una tabulazione, basta usare un altro tipo di classe di caratteri: un backslash seguito da un carattere.
Fa al caso nostro \s che rappresenta uno spazio, una tabulazione od un ritorno a capo od altre spaziature.
E se temiamo che vi siano più caratteri di spaziatura tra le parole possiamo usare i quantificatori di match repetitions, per esempio + significa che il carattere che lo precede può presentarsi una o più volte.
Riassumendo il comando sarà:

$ perl -i -p -e 's/Sestri\s+Levante/Imperia/g' city.txt

Secondo esempio: cambiare data

La situazione: nella cartella ‘src’ ci sono molti file sorgenti Python di estensione ‘.py’ che contengono la data di versione 20/01/2008. Vogliamo con un unico comando modificarla in 5/11/2012. Ipotizzando che nei file le date contenute nel testo siano esclusivamente quelle di versione, un possibile comando Perl è il seguente (poiché la slash funziona da separatore dobbiamo inserirla con il carattere di escape che è il backslash quindi ‘\/’ corrisponde a ‘/’):

$ perl -p -i-bak -e 's/20\/01\/2008/5\/11\/2012/g' src/*.py

Possiamo fare di meglio generalizzando il pattern di ricerca delle date per rendere il comando indipendente dal valore attuale, con la classe ‘\d’ che corrisponde ad una cifra qualunque:

$ perl -p -i-bak -e 's/(\d{1,2})\/\d{1,2}\/\d{4}/5\/11\/2012/g' src/*.py

Abbiamo usato tra parentesi graffe una match repetition molto restrittiva: per il giorno ed il mese ricerchiamo numeri con solamente una o due cifre e per l’anno numeri solamente con quattro cifre (certo includendo anche date senza senso del tipo 0/00/0000).
A questo punto è facile modificare il formato della data in quello internazionale yyyymmdd:

$ perl -p -i-bak -e 's/(\d{1,2})\/(\d{1,2})\/(\d{4})/$3$2$1/g' src/*.py

Se inseriamo chiavi tra parentesi tonde formiamo un gruppo la cui corrispondenza sarà assegnata alle variabili $1, $2 ecc a seconda della posizione.

Esercizio: validare una data

Qual è l’espressione regolare che valida anche se non proprio rigorosamente la correttezza della data?
Suggerimento: e se utilizzassimo classi di caratteri includendo tra parentesi quadre le cifre ed il quantificatore ‘?’?

Esempio avanzato: tag html

Situazione: disponiamo di un numero elevato di file in formato html contenenti titoli racchiusi nel tag di header in questo modo:

<h3>Titolo di sezione</h3>

Tuttavia vorremmo rendere i titoli più evidenti. Dovremo quindi sostituire i tag utilizzando un livello superiore di sezione trasformando per esempio il codice precedente nel seguente dove anziché il livello 3 si usa il livello di importanza 2:

<h2>Titolo di sezione</h2>

Per utilizzare le espressioni regolari ci serve qualcosa di sofisticato perché una volta trovato un tag di apertura o di chiusura titolo, è necessario effettuare un calcolo estraendo il numero del livello attuale per diminuirlo di 1. Il testo di sosituzione è una funzione della chiave.
La strategia è la seguente: lanciare un primo comando che marchi tutti i numeri di livello e successivamente lanciare un secondo comando che esegua il calcolo.
Salviamo il file ‘test.html’ con il seguente contenuto:

<h3>Titolo di sezione livello 3</h3>
bla bla bla
<h4>Titolo di sezione livello 4</h4>
bla bla bla
<h5>Titolo di sezione livello 5</h5>
bla bla bla

Un tag di titolo html, di apertura o chiusura che sia, ha come pattern il seguente:

   <h\d> oppure <\/h\d>
   od in un unico pattern:
   <\/?h\d>

Marchiamo il numero di livello con una notazione di cui siamo sicuri non presentandosi mai nei file, per esempio racchiudere con tre caratteri chiocciola il numero di livello. Ecco il comando:

$ perl -i-bak -p -e 's/<(\/?)h(\d)>/<$1h@@@$2@@@>/g' test.html

A questo punto il più è fatto e basta dare il secondo comando che ricerca i numeri di livello precedentemente marcati, estrae il valore con un gruppo e lo sostituisce con il valore diminuito di 1:

$ perl -i-bak -p -e 's/@@@(\d)@@@/$1-1/ge' test.html

Il modificatore g cambia tutte le occorrenze, il modificatore e sta per execute e fa si che il testo sia prima valutato e poi inserito.

Ecco come appare il file dopo l’esecuzione dei comandi:

<h2>Titolo di sezione livello 3</h2>
bla bla bla
<h3>Titolo di sezione livello 4</h3>
bla bla bla
<h4>Titolo di sezione livello 5</h4>
bla bla bla

Non sono riuscito a trovare il modo di far eseguire il calcolo mescolandolo con altro testo, probabilmente perché non conosco abbastanza il Perl, perciò chi di voi trova il modo di lanciare un unico comando anziché due, vince un viaggio premio di una settimana per due persone a Juhansic Park…

Esercizio: estrarre indirizzi e-mail

Per esercizio elaborate il comando Perl per estrarre tutti gli indirizzi di posta elettronica presenti nei file di estensione ‘txt’ presenti nella directory corrente e salvarli nel file ‘email.txt’.
Se ci riuscite questa volta non vincete nulla (tempi duri per i viaggi premio), ma come consolazione potete pubblicare la soluzione nei commenti.
Suggerimenti: forse eliminando l’opzione -p e reindirizzando l’output in un file di testo…

Finale

Possiamo rilassarci adesso. Il temibile guazzabuglio di caratteri delle espressioni regolari dovrebbe fare un po’ meno paura dopo aver fatto gli esperimenti.

Rilassarsi d’accordo, ma non dimenticatevi di mandarci i vostri esempi avanzati. Potremo includerli nel post.
Grazie ed alla prossima.
Robitex