venerdì 30 gennaio 2015

Ruotare velocemente

Oggi vedremo come creare l'animazione di un oggetto che ruota velocemente. Questo è un argomento dove molto programmatori sono esperti nel codice, ma mancano di senso praticano e si impazziscono per raggiungere prestazioni inutili.
Prima di affrontare questo argomento dal punto di vista informatico, bisogna fare una premessa dal punto di vista tecnico, non ha senso cercare di essere realmente veloci, molte volte basta far sentire la velocità, magari. Inoltre gli schermi hanno una frequenza di aggiornamento di 60Hz, cioè ogni 0.017 secondi, ogni variazione sotto questo tempo è ignorata. Quindi basterà aumentare l'angolo di rotazione ad ogni aggiornamento, invece di aumentare il numero degli aggiornamenti, per avere l'effetto desiderato.
Fatta questa premessa, passiamo al codice.  Creiamo uno stack con un poligono, un pulsante e uno scroller che chiameremo angolo:
Per ruotarlo basta sfruttare la proprietà angle.
Scrivendo questo codice, possiamo ruotare il triangolo ad ogni fotogramma dell'angolo voluto:

on mouseUp
   if the label of me is "START" then
      set the label of me to "STOP"
      ruotafigura
   else
      set the label of me to "START"      
   end if  
end mouseUp

on ruotafigura
   if the label of me is "START" then
      exit ruotafigura
   end if
   put the thumbpos of scrollbar "angolo" into Dangolo
   put the angle of graphic 1 into curangolo
   put dangolo + curangolo into curangolo
   set the angle of graphic 1 to curangolo
   send ruotafigura to me in 0.017 sec #non ha senso scendere sotto questo valore
end ruotafigura

E questo è il risultato:
Notate come se la velocità supera quella del monitor, si creano strani effetti ottici stroboscopici  (ad esempio che sembra ruotare all'indietro), come nella realtà.

giovedì 29 gennaio 2015

Piccoli problemi di manutenzione

Da oggi, quando si traducono i post utilizzando Google translator (il menù in alto a destra), il codice dei programmi non verrà modificato. Ciò è possibile grazie al codice:

class=notranslate

che ho aggiunto in tutti (o quasi) gli elementi che hanno del codice.
Per fare ciò estratto il backup del blog, che blogger fornisce sotto forma di XML, ho sostituito il codice e ho importato il file XML. Qui nasce il problema, blogger non sostituisce i post, ma li aggiunge, così mi sono ritrovato con tutti i post doppi.
Ho cancellato tutti i doppioni, ma se trovate qualche link mancante, per favore segnalatemelo.

mercoledì 28 gennaio 2015

Salvare le immagini in un database

Oggi vedremo come salvare le immagini dentro un database per poi utilizzarle successivamente.
In livecode potete sfruttare due informazioni riguardo le immagini: la proprietà imagedata e la proprietà text. Queste due proprietà rappresentano l'immagine, ma in due modi diversi. La proprietà imagedata contiene le informazioni sui pixels dell'immagine e basta; la proprietà text contiene più informazioni: il tipo di immagine (bmp,jpg, ecc.), il tipo di compressione dei dati, i pixels, ecc.
Se dobbiamo lavorare con più immagini di diverso formato (jpg, gif, png, ecc.), non possiamo mettere direttamente solo l'imagedata in una immagine di livecode, perchè se i formati sono differenti livecode dà errore e l'immagine non compare.
Dobbiamo lavorare con la proprietà text, ma vediamo nel dettaglio come fare.
Per scegliere un'immagine da caricare conviene utilizzare questo codice:

answer file "Scegli il nuovo file per l'immagine da salvare:"
if the result is not "Cancel" then
   put it into tpath
   lock screen
   put the rect of image "logo" into temp
   put url ("binfile:" & tpath) into image 1
   set the rect of image 1 to temp
   unlock screen
end if

Notate due cose, l'immagine può non avere la dimensione (altezza e larghezza) desiderata, memorizzando prima la proprietà rect e poi impostandola dopo aver caricato l'immagine, non rischiamo di trovarci immagini con dimensioni assurde fluttuanti  in giro per il programma.
Il secondo elemento da notare è il codice per mettere tutti i dati dell'immagine del computer dentro al controllo immagine di livecode (che ho chiamato semplicemente image 1):

   put url ("binfile:" & tpath) into image 1

solo così la nostra immagine image 1 contiene la proprietà text.
Il database dovrà avere un campo di tipo TEXT (testo), ciò ci permette di non dover impazzirci con i dati in formato binario, che di solito sono un problema quando si trasferiscono da un sistema ad un altro.
Ora i dati dell'immagine, cioè la proprietà text,  deve essere salvata nel database preservando tutte le informazioni, il sistema migliore è utilizzare la funzione base64encode(); in questo moto tutti i bit sono trasformati in caratteri accettati dai campi text dei database. Ecco un esempio di codice per inserire un'immagine in un database:

put base64encode(the text of image 1) into temp
put "UPDATE bandiere SET immagine='"& temp &"' WHERE nome='italia' ;" into tSQL
revExecuteSQL connID,tSQL

Per recuperare l'immagine, basta fare il procedimento inverso. La proprietà si ottiene utilizzando la funzione base64decode(), e poi la inseriamo nel controllo immagine, nel nostro caso image 1, di livecode.

put "SELECT immagine FROM bandiere WHERE nome='italia' "   into tSQL
put revDataFromQuery(tab,return,connID,tSQL) into tRecord
lock screen
put the rect of image 1 into tempR   
put base64decode(tRecord) into temp
put temp into image 1         
set the rect of image 1 to tempR
unlock screen

Separare i dati utilizzando il carattere TAB è molto utile, perchè se dovete richiedere più dati insieme non avrete possibilità di confondere i dati, poichè il carattere TAB non esce dalla funzione base64encode().

martedì 27 gennaio 2015

Cifratura a chiave asimmetrica

Nel post precedente abbiamo visto come cifrare utilizzando un sistema a chiave simmetrica, oggi vedremo come cifrare utilizzando un sistema a chiave asimmetrica.
Prima di vedere gli strumenti che livecode ci mette a disposizione, preferisco fare un'introduzione a questo nuovo tipo di cifratura. Questo sistema è di tipo molto recente, e basa la sua affidabilità sulla lentezza dei computer moderni. Quando si vuole offuscare un testo con questo sistema, si generano una coppia di chiavi: una pubblica e una privata. Chi vuole inviarvi un testo deve cifrarlo utilizzando la vostra chiave pubblica, mentre solo voi in possesso della chiave controparte privata sarete in grado di decifrarlo.
Quindi lo scambio di informazioni fra due persone si può ottenere solo con 2 coppie di chiave, una coppia per destinatario; ecco uno schema esemplificatore:
Finchè i nostri computer non saranno in grado di risalire velocemente alla chiave pubblica dalla chiave privata, questo sistema sarà sicuro. D'altro canto è sempre matematicamente possibile risalire alla chiave pubblica per tentativi con i computer, ma il tempo attuale è sui 100 anni.
Enti governativi con a disposizione enormi gruppi di calcolatori, possono ridurre questo tempo utilizzando una potenza di calcolo molto elevata, e la cifratura di tipo simmetrico allora diviene più sicura. Altri sostenitori della cifratura asimmetrica preferiscono allungare in numero di bit di cui è formata la chiave, poichè questo allunga il tempo di elaborazione per scovare la chiave privata della chiave pubblica; ma questo stratagemma allunga anche il tempo per decifrare un messaggio, anche avendo la chiave privata.
A titolo di esempio generiamo una coppia di chiavi RSA a 512 bit. Quella pubblica sarà:

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALaULMjivN2L2xGBnUTqyGAwFY9AJE6b
8bT0CZPA9XMt+M0DULRzE5lL6JkstBAqep3iopd0/285lFnoSyVYQkkCAwEAAQ==
-----END PUBLIC KEY-----


Notate che è obbligatorio mettere anche i trattini e le scritte BEGIN/END public key.
Quella privata sarà:

-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBALaULMjivN2L2xGBnUTqyGAwFY9AJE6b8bT0CZPA9XMt+M0DULRz
E5lL6JkstBAqep3iopd0/285lFnoSyVYQkkCAwEAAQJAcRn9XDxJLxzyCjg2ynh+
xEdFM8ZSN3gXFTePrz37TuuBZJquvi3d5LtfS8yLX0Ucy6PcndlsDY5TCJjdBAN+
uQIhAOMeEfwF2PHzhs/Q8eE6h4X8l2++UtN01QUURywxM483AiEAzcwgCP7IKa1h
FneEd5RErzywIGMG5NFtrIzL5sOcen8CIQDSZJ3WcPhLEwTU6UPZGKZJCfijjJUf
zEA151YTazTPOwIhAIaxyW3ZxAxzLA5WX18cre+72tL3vXVaFVxQMsxwzyPlAiEA
4xaelAVHHsClDuCw6i3NkoYTD7wg9ysNx1d/1nbMB98=
-----END RSA PRIVATE KEY-----


Facciamo uno stack contenente  sia il messaggio che vogliamo cifrare, sia le chiavi (le potete generare anche on line dal sito: http://travistidwell.com/jsencrypt/demo/).

Ora dobbiamo considerare che il sistema RSA prevede che il messaggio sia un multiplo di 52 lettere, quindi bisogna fare un controllo sul testo e aggiungere tanti spazi vuoti, quanti necessitiamo per ottenere un testo lungo un multiplo di 52 lettere. Nel pulsante cifra possiamo mettere il seguente codice:

on mouseUp
   put the text of field "testo" into testo
   put the number of chars of testo into lungtesto
   put round(lungtesto / 52) into cicli
   if (( lungtesto mod 52) is not 0 ) then
      put cicli + 1 into cicli
      put lungtesto mod 52 into temp
      #aggiungiamo gli spazi necessari
      repeat for temp times
         put " " after testo
      end repeat
   end if
   put the text of field "publickey" into passw
   put the text of field "privatekey" into passw2
   repeat with i=1 to cicli
      put char (52 * (i-1) + 1) to (i * 52) of testo into temp
      encrypt temp using rsa with public key passw      
      if the result is not empty then
         answer the result #c'è un errore, vediamo qual è
      else
         put it after tutto         
      end if
   end repeat
   set the text of field "cifrato" to tutto   
end mouseUp


e otteniamo per ogni gruppo di 52 lettere, 64 lettere cifrate. Nel campo cifrato apparirà il testo cifrato e incomprensibile.
Notate che il sistema RSA aggiunge delle variabili casuali, quindi, nonostante il messaggio originale sia sempre lo stesso, il risultato cifrato è sempre diverso.
Nel codice rsa non  è virgolettato.
Ora per recuperare il testo originale dobbiamo fare il procedimento inverso, 64 lettere alla volta; per questo nel pulsante decifra possiamo mettere il seguente codice:

on mouseUp
   put the text of field "cifrato" into testo
   put the text of field "privatekey" into passw   
   put the number of chars of testo into lungtesto   
   if (lungtesto mod 64) is not 0 then
      answer "non è un messaggio cifrato con RSA"
      exit mouseup
   end if
   put lungtesto / 64 into cicli
   repeat with i=1 to cicli
      put char (64 * (i-1) + 1) to (i * 64) of testo into temp
      decrypt temp using rsa with private key passw
      put it after tutto
   end repeat   
   answer tutto
end mouseUp


Se in decrypt usate la parola public invece di private, state solo verificando se è stato cifrato con la chiave pubblica corretta.
Ora sapete come inviare un messaggio utilizzando solo una cifratura asimmetrica.
Siccome ogni forma di dato può essere trasformato in testo con la funzione base64encode, potrete inviare anche musiche, immagini, filmati o qualsiasi altro tipo di file in maniera cifrata.

venerdì 23 gennaio 2015

Cifratura simmetrica

Livecode permette di cifrare sia in maniera simmetrica che asimmetrica. Oggi vedremo il sistema più semplice di cifratura: la cifratura simmetrica. La cifratura simmetrica è la più semplice e la più utilizzata al mondo, con la stessa parola chiave (password) si camuffa un testo,cioè si cifra, e con la stessa password si ricostruisce il testo originale, cioè si decifra.
Livecode supporta diversi sistemi di cifratura, sia asimmtrica che simmetrica; per avere una lista dei sistemi supportati e con che modalità basta utilizzare la funzione ciphernames(), ecco un breve riassunto

  • aes
  • bf
  • blowfish
  • camellia
  • cast
  • cast5
  • des
  • des3
  • desx
  • id-aes128-GCM
  • id-aes192-GCM
  • id-aes256-GCM
  • rc2
  • rc4
  • seed

Per inciso, tutti i sistemi più avanzati che dichiarano di utilizzare una cifratura più difficile di tipo asimmetrico, in realtà non riescono ad utilizzarla completamente, perchè un procedimento del genere richiede un tempo molto grande. Per questo motivi cifrano in maniera asimmetrica solo la password simmetrica di un testo cifrato in modo simmetrico.

Nel nostro caso cifreremo simmetricamente utilizzando il sistema blowfish.

Facciamo uno stack con  con i seguenti campi: testo, password e cifrato. Aggiungiamo due pulsanti: cifra e decifra. Mettiamo nel pulsante cifra il seguente codice:

on mouseUp
   put the text of field "testo" into testo
   put the text of field "password" into passw
   encrypt testo using "bf" with password passw
   set the text of field "cifrato" to it
end mouseUp

In questo modo, premendo sul pulsante cifra, nel campo cifrato apparirà il testo cifrato:
Per decifrare possiamo mettere il seguente codice nel pulsante decifra:

on mouseUp
   put the text of field "cifrato" into testo
   put the text of field "password" into passw
   decrypt testo using "bf" with password passw
   answer it
end mouseUp

Nel prossimo post vedremo come utilizzare i sistemi asimmetrici.
Il limite di sicurezza nella cifratura simmetrica risiede nel fatto che a chi inviamo un messaggio cifrato, dobbiamo far sapere anche la chiave utilizzata, e quindi se cade nelle mani di qualcun altro, anche quest'ultimo potrà decifrare i nostri messaggi.

giovedì 22 gennaio 2015

Rimuovere livecode da Linux

Nuove versioni di Livecode escono continuamente, quindi rischiate di avere il menu di avvio pieno di tutte le versione installate; per fortuna i programmatori hanno installato un sistema per eliminare le vecchie versioni su Linux in maniera semplicissima.
Tutte le versioni si installano dentro la cartella /opt/runrev, ognuna con la propria cartella:

max@max-desktop /opt/runrev $ ls
livecodecommunity-6.6.2
livecodecommunity-7.0.0-rc-1 (x86_64)
livecodecommunity-7.0.0-rc-2 (x86_64)
livecodecommunity-7.0.0 (x86_64)
livecodecommunity-7.0.1-rc-1 (x86_64)
livecodecommunity-7.0.1-rc-3 (x86_64)
livecodecommunity-7.0.1 (x86_64)



Dentro le cartelle di ogni versione c'è un file nascosto chiamato ".setup.x86", basta posizionarsi dentro la cartella /opt/runrev/, senza essere root (dopo vi chiederà la password), e lanciare il comando ".setup.x86 -uninstall" della cartella che contiene la versione da disinstallare. L'importante è non essere dentro la cartella stessa da cancellare. Ecco le schermate che vi appariranno:


mercoledì 21 gennaio 2015

Frattali

I frattali sono particolari figure geometriche che rappresentano se stesse qualunque ingrandimento fatto.
Mi sono esercitato un po' con la formula per quello di Mandenlbrot e il risultato è stato il seguente:
Nel caso di Mandrelbrot il calcolo iterativo è dato da P(z+1)= P(z)^2 + P(x,y). Il codice è il seguente:


on mouseUp
   put "1,1" into cc
   put cc & CR into nn
   delete image "frattale"
   create image "frattale"
   put field "grandezza" into kk #deve essere un numero pari
   put field "maxiter" into rip   
   set the width of image frattale to kk
   set the height of image frattale to kk
   #centriamo l'immagine
   set the loc of image "frattale" to the loc of scrollbar "progr"
   set the top of image "frattale" to the bottom of scrollbar "progr"
   set the layer of image "frattale" to 1
   repeat with x= 1 to kk
      repeat with y= 1 to kk
         put x / kk * 4 - 2 into tx
         put y / kk * 4 - 2 into ty
         put fract(tx,ty,rip) & CR after contlist
         add 1 to cont
         set the thumbpos of scrollbar "progr" to (round(100/(kk * kk) * cont) )
      end repeat
   end repeat   
   set the lista of me to contlist #per debug
   repeat for each line tLine in contlist      
      put numtochar(255) after timag
      put numtochar(tLine* 255 / rip) after timag
      put numtochar(tLine*255 / rip) after timag
      put numtochar(tLine*255 / rip) after timag      
   end repeat
   set the imagedata of image "frattale" to timag
   #answer "fatto"
end mouseUp

function fract x,y,rip
   put x & comma & y into cc
   put "0,0" into xy
   put 0 into d
   put 0 into cont
   repeat while d < 2
      add 1 to cont      
      if cont > rip then
         put 0 into cont
         exit repeat
      end if
      put compadd(compmult(xy,xy), cc) into xy
      put item 1 of xy into xx
      put item 2 of xy into yy
      put sqrt(xx^2 + yy^2) into d         
   end repeat
   return cont
end fract

function compadd aa,bb
   put item 1 of aa into aax
   put item 2 of aa into aay
   put item 1 of bb into bbx
   put item 2 of bb into bby
   put (aax + bbx) , (aay + bby) into temp
   return temp
end compadd


function compmult aa,bb
   put item 1 of aa into aax
   put item 2 of aa into aay
   put item 1 of bb into bbx
   put item 2 of bb into bby
   put (aax * bbx - aay * bby) , (aax * bby + aay * bbx) into temp   
   return temp
end compmult




Il programma completo lo potete scaricare da qui. Non è che sia entusiasta della velocità di calcolo ottenuta, voi riuscireste a migliorare il codice?