Category Archives: Coding

Epic Coding Sessions with my Music Playlist on Spotify

 

Today I recommend one of my playlists on spotify, which I created during my sleepless nights on the code. I love this playlist quite varied (but with a lot of trance music). It helps me a lot to find the right concentration, I hope it works with you too!

If you have a suggestion for new songs to add, leave a comment below.

Continue reading Epic Coding Sessions with my Music Playlist on Spotify

Mantenere dati e preferenze di un’app iOS quando l’utente effettua un aggiornamento da App Store

Ho di recente iniziato a sviluppare un’app di ricette per iOS, e come ogni buona app di questo tipo, vi è la possibilità di inserire una ricetta tra i preferiti.

Anche se la questione può sembrare semplice, in realtà la cosa è più complicata di quanto si pensi.

Analizzando il problema in profondità, dal punto di vista di uno sviluppatore, vi è il problema dell’aggiornamento dell’app.

Se io, utente, aggiorno la mia applicazione, e tra i preferiti avevo salvato 10 ricette, dopo l’aggiornamento, che fine fanno i preferiti? E’ lecito pensare, dal punto di vista di uno sviluppatore, che un aggiornamento comporti l’eliminazione della vecchia versione dell’app, dopodiché l’installazione della nuova release.

Questo problema, che può sembrare banale, in realtà non è così semplice. Ho dovuto cercare e alla fine capire da solo come risolvere il problema. Nemmeno Apple, nella sua documentazione, accenna al problema.

Andrò quindi ad analizzare la mia situazione, che può essere utile praticamente per tutte le app che necessitano della persistenza dei dati,  anche dopo un aggiornamento dell’app stessa tramite app store.

Analisi

L’applicazione sul quale ho affrontato il problema è così strutturata: ho un file .plist, contenente le mie ricette. Il plist è composto da un array, l’array al proprio interno contiene N dictionary, ognuno dei quali identifica una ricetta. Ogni dictionary (quindi ogni singola ricetta) ha al proprio interno i campi che costituiscono la ricetta (titolo, ingredienti, preparazione, categoria, etc…).

Questo .plist, verrà aggiornato di volta in volta dallo sviluppatore (da me), quando viene rilasciato un aggiornamento dell’applicazione su app store. E’ palese il fatto che NON possiamo inserire in questo caso un nuovo campo booleano “preferito” all’interno di ogni ricetta, poiché il file verrà sovrascritto durante l’aggiornamento, e quindi se l’utente aveva inserito delle ricette tra i preferiti, dopo l’aggiornamento tutti i campi “preferito” tornerebbero a FALSE, in sostanza: abbiamo perso tutti i preferiti.

plist app ricette

File System

Per comprendere a fondo il problema, è essenziale capire come funziona il file system su iOS.

La documentazione ufficiale di Apple, spiega in modo chiaro e semplice il funzionamento del file system.

In breve, ogni applicazione ha una Sandbox, ovvero un ambiente dove effettuare operazioni di IN/OUT, dove vi è la possibilità di memorizzare qualsiasi tipo di file. Lo sviluppatore, NON può accedere al di fuori della Sandbox, e ogni app ha una propria Sandbox.

sandbox di ios

All’interno della Sandbox, vi sono cinque directory, utili allo sviluppatore per lo storage dei dati. Di seguito vi è una traduzione italiana, presa da devapp, di ciò che trovate sulla guida ufficiale Apple.

ios File System directory

Siccome si presume che le nostre preferenze, che vogliamo ritrovare dopo ogni aggiornamento dell’app, siano anche “backuppate” da iTunes, dobbiamo utilizzare in questo specifico caso la directory “Documents”.

Aggiornamento da App Store

Come funziona l’aggiornamento di un’app secondo Apple? iTunes scarica l’aggiornamento in un una nuova directory, dopodiché sposta i dati contenuti nelle directory sopra elencate, dalla vecchia versione dell’app alla nuova. Se nella nuova versione dell’app, all’interno della directory Documents, viene scritta una nuova versione del nostro file (ad esempio del .plist contenente le ricette), automaticamente viene eliminata la vecchia versione. Ecco spiegato il perché non possiamo inserire i preferiti all’interno di ricette.plist. Non possiamo accedere contemporaneamente alla vecchia e alla nuova versione del file per fare un merge, dobbiamo adottare un’altra soluzione.

La soluzione

La soluzione è un secondo file (in questo caso ho utilizzato un altro .plist chiamandolo “Preferiti.plist”).

file preferiti plist struttura

In questo file, strutturato come un Dictionary contenente un solo Array di nome HandSet (che al suo interno conterrà solo tipi String), memorizzerò i titoli di ogni singola ricetta (o gli ID). Se la ricetta è all’interno di questo file, significa che è tra i preferiti, e se aggiornerò il file Ricette.plist, non dovrò occuparmi di quali ricette sono tra i preferiti o meno, perché è in un file a parte. Questo significa che se una ricetta era tra i preferiti, rimane dov’è, e all’utente viene data la possibilità di inserire nuove ricette tra i preferiti.


//Dichiaro la path del file Preferiti.plist presente nel bundle, che sarà

//successivamente scritta in Documents (all'interno della sandbox)

NSString *finalPath = [[NSBundle mainBundle] pathForResource:@"Preferiti" ofType:@"plist"];

/* PERMETTE DI SCRIVERE IL FILE "Preferiti.plist" NELLA CORRETTA CARTELLA "Documents" DELLA SANDBOX */

NSFileManager *fileManager = [NSFileManager defaultManager];

NSError *error;

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *DocPath = [documentsDirectory stringByAppendingPathComponent:@"Preferiti.plist"];

if ([fileManager fileExistsAtPath:DocPath] == NO) { //se Preferiti.plist non esiste (è la prima volta che l'app viene aperta) lo scrive.

[fileManager copyItemAtPath:finalPath toPath:DocPath error:&error];

NSLog(@"SCRITTO FILE INIZIALE Preferiti.plist");

}

//se invece è un aggiornamento, non deve fare nulla, perché significa che già esiste un file Preferiti.plist nella directory Documents

Quando effettuiamo un’operazione sul file .plist, dobbiamo stare ben attenti a prelevare ciò che era già presente al suo interno, dopodiché effettuare un merge tra i vecchi dati e quelli che stiamo andando ad inserire (in questo caso, un nuovo preferito). Sui file .plist non possiamo semplicemente aggiungere un oggetto, in quanto ogni volta che richiameremo

[dati writeToFile:path atomically:YES];

verrà creato e scritto un nuovo file (e se già presente, il vecchio sarà sovrascritto).

//AGGIUNTA DI UN NUOVO VALORE IN PREFERITI.PLIST
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *DocPath = [documentsDirectory stringByAppendingPathComponent:nomePlist];

NSMutableDictionary *addData = [NSMutableDictionary dictionaryWithContentsOfFile:DocPath];

NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:DocPath];

NSArray *oldHandsets = [dict valueForKey:@"HandSet"]; //vecchi dati presente in preferiti.plist

NSArray *newHandsets = [[NSArray alloc]initWithObjects:@"nuovo preferito string", nil]; //nuovo oggetto-array di oggetti da inserire tra i preferiti

NSMutableSet *mergeHandsets = [NSMutableSet setWithArray:oldHandsets];

[mergeHandsets addObjectsFromArray:newHandsets]; //merge dei dati (vecchi e nuovi)

//aggiungo i nuovi oggetti al plist, nell'Array di nome HandSet

[addData setObject:[mergeHandsets allObjects] forKey:@"HandSet"];

//scrivo il nuovo file con i cambiamenti apportati

[addData writeToFile:DocPath atomically:YES];

E per eliminare un dato?


 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *DocPath = [documentsDirectory stringByAppendingPathComponent:nomePlist];

    NSMutableDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:DocPath];

    NSMutableArray *dataFromPlist = [dict valueForKey:@"HandSet"];

    [dataFromPlist removeObject:@"string da rimuovere"];

    [dict setObject:dataFromPlist forKey:@"HandSet"];

    [dict writeToFile:DocPath atomically:YES];

Ovviamente, prima di cancellare un dato dovete assicurarvi che sia presente, quindi tocca a voi gestire tutte le varie eccezioni che potrebbero essere generate.

Utilizzando questo sistema, possiamo memorizzare delle preferenze o un qualsiasi tipo di dato (e non per forza un file .plist), senza perdere informazioni durante un aggiornamento eseguito tramite app store.

Se questa guida ti è stata utile, fammelo sapere nei commenti! 😉

Cheers!

Big Data: esempio di codice Java per estrarre tweets da Twitter

Nell’ambito dei Big Data, le aziende investono milioni per estrarre più informazioni possibili da internet, e in particolare dai social network.

Al contrario di Facebook, dove le informazioni sono protette dal livello di privacy impostato dagli utenti, quasi tutti gli account di twitter sono liberi e accessibili da chiunque. La realtà dei fatti è che ogni vostro tweet è catturato da qualcuno e viene rivenduto per trarne profitto. Trarne profitto come? Analisi di mercato, statistiche e tanta altra roba che per le aziende è oro.

BigData - estrazione tweets da twitterImmaginiamo ad esempio che la Ferrero voglia analizzare il livello di gradimento di uno dei suoi prodotti, ad esempio la Nutella che tutti conosciamo. Attraverso l’estrazione dei tweets con alcune parole chiave ben studiate e l’analisi di questi dati (cosa tutt’altro che semplice), la Ferrero o chi per lei, riesce ad ottenere il feedback di gradimento del prodotto da parte degli utenti, oppure nello specifico, per cosa viene principalmente usata (spalmata sul pane, preparare torte, etc…). Sono infiniti i benefici che si possono trarre dai Big Data, e chi lavora in questo settore solitamente viene pagato fior di quattrini.

Il problema di lavorare con questo tipo di dati, è la mole di informazioni che si riescono a catturare, in quanto col passare del tempo le informazioni salgono in modo esponenziale e il vostro pc casalingo non riuscirebbe mai a gestire il lavoro in entrata (sia per quanto riguarda la potenza di calcolo (cpu), sia per lo storage di dati (che raggiunge anche petabyte ogni settimana), sia per la velocità di connessione alla rete).

Ad ogni modo, se ci si limita ai soli tweets, Twitter offre delle API REST, che attraverso delle chiamate JSON restituisce tutti i tweets con la query richiesta. Nell’esempio di codice java che segue sotto, mi limiterò ad usare il Public Stream fornito da Twitter, ma sappi che ci sono altri modi di accedere ai tweets (in modo più limitato, e utili ad esempio qualora si volesse scrivere un client).

Attenzione: Twitter agli account “semplici” limita questo tipo di utilizzo, e permette di accedere solo all’1% dei tweets mondiali, che ad ogni modo è una quantità enorme di informazioni. Se cercate quindi di estrarre tutti i tweets con la parola “Android”, e questi sono più dell’1% sul totale, alcuni tweets li perderete. Il lavoro di estrazione dei tweets è possibile eseguirlo anche su un comune PC, non vi è bisogno di avere delle super macchine.

Per l’estrazione dei tweets uso la libreria java (non ufficiale) Twitter4J. Grazie a questa libreria posso integrare facilmente all’interno delle mie applicazioni Java i servizi offerti da Twitter. La libreria è 100% codice java, e lavora con ogni versione superiore alla 5. Il framework lavora correttamente anche con la piattaforma Android e il Google App Engine.

Nel codice che vedi di seguito, ho utilizzato delle dipendenze Maven per importare la libreria Twitter4J. Se interessato, gli snippet sono i seguenti:


<dependency>
 <groupId>org.twitter4j</groupId>
 <artifactId>twitter4j-core</artifactId>
 <version>3.0.3</version>
 </dependency>

 <dependency>
 <groupId>org.twitter4j</groupId>
 <artifactId>twitter4j-stream</artifactId>
 <version>3.0.3</version>
 </dependency>

Passiamo al codice Java vero e proprio, abbastanza semplice da comprendere. Per ulteriori info su alcune classi utilizzate, fai riferimento alla documentazione.


//© Paolo Musolino - http://www.codeido.com
public class App
{
 public static void main( String[] args )
 {
 //ESTRAZIONE DEI TWEETS

 System.out.println( "www.codeido.com" );

 StatusListener listener = new StatusListener(){

 public void onStatus(Status status) {

 System.out.println(status.getUser().getName() + " : " + status.getText());

 }
 public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {}
 public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
 // System.out.print(numberOfLimitedStatuses+"\n"); //stampa il numero di tweets che vengono persi
 }
 public void onException(Exception ex) {
 ex.printStackTrace();
 }

public void onScrubGeo(long l, long l1) {
 throw new UnsupportedOperationException("Not supported yet.");
 }

public void onStallWarning(StallWarning sw) {
 throw new UnsupportedOperationException("Not supported yet.");
 }
 };
 ConfigurationBuilder cb = new ConfigurationBuilder();
 cb.setUser("vostro_username_twitter");
 cb.setPassword("vostra_password_account_twitter");

 TwitterStream twitterStream = new TwitterStreamFactory(cb.build()).getInstance();
 twitterStream.addListener(listener);
 FilterQuery filtro=new FilterQuery();
 String[] arrayQuery={"codeido", "big data", "bigdata"}; //stringhe che verranno cercare all'interno dei tweets.
 filtro.track(paroleChiave);
 twitterStream.filter(filtro);

 }
}
 }

Fanne buon uso e ricordati di condividere questo articolo.

Alla prossima.

Paolo

Rise of Coding: Why We Should All Learn a Little Code

Enthusiasm for learning programming languages is on the rise. And coding is no longer the domain of self-taught savants or formal C.S. students. Students of all ages and disciplines are recognizing the benefits of being more code fluent. Plenty of free, in-browser online tutorials have risen to meet this need. One site, Codecademy, had over 1 million users pledge 2012 as their “code year” and sign up for their free tutorials on Java, HTML and CSS for beginners.

This is a great sign for the future of work in the U.S. Coding familiarity is becoming more of an asset across all industries. You don’t need to know how to reprogram your computer to operate it, but understanding how it works will help you imagine how programs can change to better serve your industry. So, if you’re among those of us who’ve always thought programming was impossibly hard or reserved for the tech-minded, consider learning a little code. There’s never been a better (or more supportive) time to get ahead of the curve. [SOURCE: OnlineCollege]

An implementation of the algorithm “DES” written in Java.

The algorithms described in this standard specifies both enciphering and deciphering operations which are based on a binary number called a key.

A DES key consists of 64 binary digits (“0″s or “1”s) of which 56 bits are randomly generated and used directly by the algorithm. The other 8 bits, which are not used by the algorithm, may be used for error detection. The 8 error detecting bits are set to make the parity of each 8-bit byte of the key odd, i.e., there is an odd number of “1”s in each 8-bit byte1. A TDEA key consists of three DES keys, which is also referred to as a key bundle. Authorized users of encrypted computer data must have the key that was used to encipher the data in order to decrypt it. The encryption algorithms specified in this standard are commonly known among those using the standard. The cryptographic security of the data depends on the security provided for the key used to encipher and decipher the data.

Data can be recovered from cipher only by using exactly the same key used to encipher it. Unauthorized recipients of the cipher who know the algorithm but do not have the correct key cannot derive the original data algorithmically. However, it may be feasible to determine the key by a brute force “exhaustion attack.” Also, anyone who does have the key and the algorithm can easily decipher the cipher and obtain the original data. A standard algorithm based on a secure key thus provides a basis for exchanging encrypted computer data by issuing the key used to encipher it to those authorized to have the data.

For more details, see this document.

This is the main written in java:
</pre>
import java.io.UTFDataFormatException;
import java.nio.charset.Charset;
/**
 *
 * @author Paolo Musolino
 */
public class EsameCrittografia {

&nbsp;

private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
 /**
 * @param args
 */
 public static void main(String[] args) {


 try{


 String testoInChiaro = "questo è l'algoritmo des";

 //DES
 String k = "5qw8sd4h";

 System.out.println("Testo in chiaro: "+testoInChiaro);

 byte[] enc = DES.encrypt(testoInChiaro.getBytes(), k.getBytes());
 System.out.println("Testo criptato con DES: "+new String(enc));

byte[] dec = DES.decrypt(enc, k.getBytes());
 System.out.println("Testo decriptato con DES: "+new String(dec));
 System.out.println("------------------");



}catch(Exception e){
 e.printStackTrace();
 }
 }

}
<pre>

This is the Java class that contains the operation of the des (comments are written in Italian):

</pre>
/**
 *
 * @author pmusolino
 */
public class DES {
 // tabella di permutazione iniziale
 private static int[] IP = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36,
 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32,
 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19,
 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 };
 // tabella di permutazione finale
 private static int[] invIP = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47,
 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13,
 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51,
 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17,
 57, 25 };
 // Permutazione P (nel metodo f(Feistel))
 private static int[] P = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5,
 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4,
 25

};
 // chiave di permutazione iniziale 64 bit => 56 bit
 private static int[] PC1 = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34,
 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63,
 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53,
 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 };
 // chiave di permutazione al round i 56 => 48
 private static int[] PC2 = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55,
 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29,
 32 };
 // shift della chiave per ogni round
 private static int[] keyShift = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
 2, 1 };
 // tabella di permutazione per l'espansione nella funzione di feistel
 private static int[] expandTbl = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8,
 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21,
 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32,
 1 };

 // scatola di sostituzione s-box
 private static int[][][] sboxes = {
 { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
 },
 { { 15, 1, 8, 14, 6, 11, 3, 2, 9, 7, 2, 13, 12, 0, 5, 10 },
 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
 },
 { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
 },
 { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
 },
 { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
 { 11, 8, 12, 7, 1, 14, 2, 12, 6, 15, 0, 9, 10, 4, 5, 3 }
 },
 { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }

},
 { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }

},
 { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
 { 2, 1, 14, 7, 4, 10, 18, 13, 15, 12, 9, 0, 3, 5, 6, 11 }

} };

// contiene le subkeys
 private static byte[][] K;

&nbsp;

//setta i bit all'interno dell'array di byte che gli passiamo con val nella posizione prestabilita
 private static void setBit(byte[] data, int pos, int val) {
 int posByte = pos / 8;
 int posBit = pos % 8;
 byte tmpB = data[posByte];
 tmpB = (byte) (((0xFF7F >> posBit) & tmpB) & 0x00FF);
 byte newByte = (byte) ((val << (8 - (posBit + 1))) | tmpB);
 data[posByte] = newByte;
 }

//funzione che estrae un bit (singolo) da un array di byte.
 private static int extractBit(byte[] data, int pos) {
 int posByte = pos / 8;
 int posBit = pos % 8;
 byte tmpB = data[posByte];
 int bit = tmpB >> (8 - (posBit + 1)) & 0x0001;
 return bit;
 }

//rotazione verso sinistra, di uno o due bit.
 //Questa funzione viene richiamata nella generazione delle chiavi.
 //entrambe le metà vengono fatte slittare verso sinistra di 1 o 2 bit
 // (per i round 1, 2, 9, 16 lo shift, cioè lo slittamento, è di 1 bit, per gli altri è di 2)
 private static byte[] rotLeft(byte[] input, int len, int pas) {
 int nrBytes = (len - 1) / 8 + 1;
 byte[] out = new byte[nrBytes];
 for (int i = 0; i < len; i++) {
 int val = extractBit(input, (i + pas) % len);
 setBit(out, i, val);
 }
 return out;
 }

//questo metodo estrae i bit dividendo il testo in chiaro da 64 bit in due metà, richiamata in encrypt64Bloc
 private static byte[] extractBits(byte[] input, int pos, int n) {
 int numOfBytes = (n - 1) / 8 + 1;
 byte[] out = new byte[numOfBytes];
 for (int i = 0; i < n; i++) {
 int val = extractBit(input, pos + i);
 setBit(out, i, val);
 }
 return out;

}


 //permuta i byte in input con quelli presente su una delle tavole (esempio: IP, inv IP)
 private static byte[] permutFunc(byte[] input, int[] table) {
 int nrBytes = (table.length - 1) / 8 + 1;
 byte[] out = new byte[nrBytes];
 for (int i = 0; i < table.length; i++) {
 int val = extractBit(input, table[i] - 1);
 setBit(out, i, val);
 }
 return out;

}

 //funzione che permette lo xor dei bit, ed è utilizzato per esempio nel terzo passaggio del DES
 //poiché ai 48 bit dell'espansione viene applicato un or esclusivo con la chiave
 //di ciclo a 48 bit.
 private static byte[] xor_func(byte[] a, byte[] b) {
 byte[] out = new byte[a.length];
 for (int i = 0; i < a.length; i++) {
 out[i] = (byte) (a[i] ^ b[i]);
 }
 return out;

}

 /*
 * E' la funzione che cripta realmente, quella che elabora blocchi da 64 bit,
 * che divide il blocco in due parti uguali da 32 bit, e che esegue tutte le operazioni (richiamando
 * le altre funzioni).
 * Il risultato viene poi utilizzato in "encrypt" che compatta tutto il testo in chiaro in blocchi
 * maggiori di 64 bit (se più lungo ovviamente).
 */
 private static byte[] encrypt64Bloc(byte[] bloc,byte[][] subkeys, boolean isDecrypt) {
 byte[] tmp = new byte[bloc.length];
 byte[] R = new byte[bloc.length / 2];
 byte[] L = new byte[bloc.length / 2];

tmp = permutFunc(bloc, IP);

L = extractBits(tmp, 0, IP.length/2);
 R = extractBits(tmp, IP.length/2, IP.length/2);

for (int i = 0; i < 16; i++) {
 byte[] tmpR = R;
 if(isDecrypt)
 R = f_func(R, subkeys[15-i]);
 else
 R = f_func(R,subkeys[i]);
 R = xor_func(L, R);
 L = tmpR;
 }

tmp = concatBits(R, IP.length/2, L, IP.length/2);

tmp = permutFunc(tmp, invIP);
 return tmp;
 }

/* La funzione Feistel, opera su mezzo blocco (32 bit) per volta e consiste di 4 passi.
 1. Espansione - il mezzo blocco di 32 bit è espanso fino a 48 bit utilizzando la permutazione
 di espansione che duplica alcuni bit.
 2. Miscelazione con la chiave - il risultato è combinato con una sottochiave usando
 * un'operazione di XOR. Sedici sottochiavi di 48 bit — una per ogni ciclo —
 * sono derivate dalla chiave principale usando il gestore della chiave (descritto più avanti
 * nella funzione generateSubKeys).
 3- Sostituzione - dopo la miscelazione con la sottochiave, il blocco viene diviso in 8 parti
 * di 6 bit prima del processamento con le S-box.
 * Ognuna delle 8 S-box sostituisce 6 bit in input con 4 bit in output mediante una trasformazione
 * non lineare effettuata mediante una tabella. Le S-box forniscono il cuore della sicurezza del DES
 * — senza di esse, la cifratura sarebbe lineare e quindi facilmente violabile.
 * Permutazione - infine, i 32 bit risultanti dalle S-box sono riordinati in base alle permutazioni
 * fisse della Permutation-box.
 4. L'alternanza di sostituzioni mediante le S-box, le permutazioni con la P-box
 * e le espansioni forniscono la cosiddetta confusione e diffusione,
 * (concetto identificato da Claude Shannon negli anni '40) come condizione necessaria
 * per rendere pratica e sicura la cifratura.
 */
 private static byte[] f_func(byte[] R, byte[] K) {
 byte[] tmp;
 tmp = permutFunc(R, expandTbl);
 tmp = xor_func(tmp, K);
 tmp = s_func(tmp);
 tmp = permutFunc(tmp, P);
 return tmp;
 }

/*
 * Utilizzata nel 4° passaggio di ogni round del DES .
 * Il risultato dello XOR del 3° passaggio viene utilizzato
 * nella S-box (sboxes). Il risultato è una parola di 32 bit.
 */
 private static byte[] s_func(byte[] in) {
 in = separateBytes(in, 6);
 byte[] out = new byte[in.length / 2];
 int halfByte = 0;
 for (int b = 0; b < in.length; b++) {
 byte valByte = in[b];
 int r = 2 * (valByte >> 7 & 0x0001) + (valByte >> 2 & 0x0001);
 int c = valByte >> 3 & 0x000F;
 int val = sboxes[b][r];
 if (b % 2 == 0)
 halfByte = val;
 else
 out[b / 2] = (byte) (16 * halfByte + val);
 }
 return out;
 }


 // dopo la miscelazione con la sottochiave, il blocco viene diviso in 8 parti di 6 bit.
 //Viene utilizzata nella s_func.
 private static byte[] separateBytes(byte[] in, int len) {
 int numOfBytes = (8 * in.length - 1) / len + 1;
 byte[] out = new byte[numOfBytes];
 for (int i = 0; i < numOfBytes; i++) {
 for (int j = 0; j < len; j++) {
 int val = extractBit(in, len * i + j);
 setBit(out, 8 * i + j, val);
 }
 }
 return out;
 }

 //Metodo utilizzato nella generazione delle subKeys, per concatenere le due metà della chiave.
 private static byte[] concatBits(byte[] a, int aLen, byte[] b, int bLen) {
 int numOfBytes = (aLen + bLen - 1) / 8 + 1;
 byte[] out = new byte[numOfBytes];
 int j = 0;
 for (int i = 0; i < aLen; i++) {
 int val = extractBit(a, i);
 setBit(out, j, val);
 j++;
 }
 for (int i = 0; i < bLen; i++) {
 int val = extractBit(b, i);
 setBit(out, j, val);
 j++;
 }
 return out;
 }

 /*
 * Elimina il padding.
 * Se il testo in chiaro non è un multiplo esatto,
 * è necessario riempire il tutto prima della cifratura (pad)
 * con l'aggiunta di una stringa di padding.
 * Quando si decodifica, la funzione ricevente (quella che che decripta)
 * ha bisogno di eliminare il padding.
 */
 private static byte[] deletePadding(byte[] input) {
 int count = 0;

int i = input.length - 1;
 while (input[i] == 0) {
 count++;
 i--;
 }

byte[] tmp = new byte[input.length - count - 1];
 System.arraycopy(input, 0, tmp, 0, tmp.length);
 return tmp;
 }
 /*Genera le SubKeys di ogni round. Inizialmente, vengono selezionati 56 bit della chiave
 * dagli iniziali 64 bit mediante la funzione permutFunc (PC-1) -
 * i rimanenti 8 bit sono scartati o utilizzati come bit di controllo della parità.
 * I 56 vengono poi suddivisi in 2 metà di 28 bit; ogni metà è poi trattata separatamente.
 * Nei cicli successivi entrambe le metà vengono fatte slittare verso sinistra di 1 o 2 bit
 * (per i round 1, 2, 9, 16 lo shift, cioè lo slittamento, è di 1 bit, per gli altri è di 2)
 * e quindi vengono scelti 48 bit per la sottochiave mediante la funzione Permuted Choice 2 (PC-2)
 * - 24 bit dalla metà di sinistra e 24 bit da quella di destra. La rotazione significa che
 * in ogni sottochiave è usato un insieme differente di bit; ogni bit è usato più o meno in
 * 14 delle 16 sottochiavi. Il gestore delle chiavi per la decifratura è simile -
 * deve generare le chiavi nell'ordine inverso quindi la rotazione è verso destra invece che verso
 * sinistra.
 */
 private static byte[][] generateSubKeys(byte[] key) {
 byte[][] tmp = new byte[16][];
 byte[] tmpK = permutFunc(key, PC1);

byte[] C = extractBits(tmpK, 0, PC1.length/2);
 byte[] D = extractBits(tmpK, PC1.length/2, PC1.length/2);

for (int i = 0; i < 16; i++) {

C = rotLeft(C, 28, keyShift[i]);
 D = rotLeft(D, 28, keyShift[i]);

byte[] cd = concatBits(C, 28, D, 28);

tmp[i] = permutFunc(cd, PC2);
 }

return tmp;
 }

 //è la funzione richiamata nel main che cripta il messaggio
 public static byte[] encrypt(byte[] data, byte[] key) {
 int lenght=0;
 byte[] padding = new byte[1];
 int i;
 lenght = 8 - data.length % 8;
 padding = new byte[lenght];
 padding[0] = (byte) 0x80;

 for (i = 1; i < lenght; i++)
 padding[i] = 0;

byte[] tmp = new byte[data.length + lenght];
 byte[] bloc = new byte[8];

K = generateSubKeys(key);

 int count = 0;

for (i = 0; i < data.length + lenght; i++) {
 if (i > 0 && i % 8 == 0) {
 bloc = encrypt64Bloc(bloc,K, false);
 System.arraycopy(bloc, 0, tmp, i - 8, bloc.length);
 }
 if (i < data.length)
 bloc[i % 8] = data[i];
 else{
 bloc[i % 8] = padding[count % 8];
 count++;
 }
 }
 if(bloc.length == 8){
 bloc = encrypt64Bloc(bloc,K, false);
 System.arraycopy(bloc, 0, tmp, i - 8, bloc.length);
 }
 return tmp;
 }





 //è la funzione richiamata nel main che decripta il messaggio
 public static byte[] decrypt(byte[] data, byte[] key) {
 int i;
 byte[] tmp = new byte[data.length];
 byte[] bloc = new byte[8];

 K = generateSubKeys(key);

for (i = 0; i < data.length; i++) {
 if (i > 0 && i % 8 == 0) {
 bloc = encrypt64Bloc(bloc,K, true);
 System.arraycopy(bloc, 0, tmp, i - 8, bloc.length);
 }
 if (i < data.length)
 bloc[i % 8] = data[i];
 }
 bloc = encrypt64Bloc(bloc,K, true);
 System.arraycopy(bloc, 0, tmp, i - 8, bloc.length);
 tmp = deletePadding(tmp);

return tmp;
 }
}
<pre>

Fibonacci Search Algorithm, written in C

The Fibonacci search technique is a method of searching a sorted array using a divide and conquer algorithm that narrows down possible locations with the aid of Fibonacci numbers. Compared to binary search, Fibonacci search examines locations whose addresses have lower dispersion. Therefore, when the elements being searched have non-uniform access memory storage (i.e., the time needed to access a storage location varies depending on the location previously accessed), the Fibonacci search has an advantage over binary search in slightly reducing the average time needed to access a storage location. The typical example of non-uniform access storage is that of a magnetic tape, where the time to access a particular element is proportional to its distance from the element currently under the tape’s head. Note, however, that large arrays not fitting in cache or even in RAM can also be considered as non-uniform access examples. Fibonacci search has a complexity of O(log(x)).

Fibonacci Search Algorithm, written in C:

#include <stdio.h>

int ricerca_fib(int a[], int n, long x)
{ 
	int inf=0, pos, k;
	static int kk= -1, nn=-1, fib[]={0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141};

if(nn!=n)
{ 
	k=0;
	while(fib[k]<n) k++;
	kk=k;
	nn=n;
}
else
	k=kk;

while(k>0)
{
	pos=inf+fib[--k];
	if((pos>=n)||(x<a[pos]));
	else if (x>a[pos])
	{
		inf=pos+1;
		k--;
    }

	else {
		return pos;
	}
}
	return -1;
}

Recursive Quicksort Algorithm written in C language [with example step-by-step]

Quicksort is a sorting algorithm developed by C. A. R. Hoare that, on average, makes O(nlogn) (big O notation) comparisons to sort n items. In the worst case, it makes O(n2) comparisons, though if implemented correctly this behavior is rare. Typically, quicksort is significantly faster in practice than other O(nlogn) algorithms, because its inner loop can be efficiently implemented on most architectures, and in most real-world data, it is possible to make design choices that minimize the probability of requiring quadratic time. Additionally, quicksort tends to make excellent usage of the memory hierarchy, taking perfect advantage of virtual memory and available caches. Although quicksort is usually not implemented as an in-place sort, it is possible to create such an implementation.
Quicksort (also known as “partition-exchange sort”) is a comparison sort and, in efficient implementations, is not a stable sort.
Continue reading Recursive Quicksort Algorithm written in C language [with example step-by-step]

Massimo e Minimo di un array in C

Con le seguenti funzioni, scritte in linguaggio C, è possibile trovare il valore massimo e il valore minimo all’interno di un array di n elementi interi. Con piccolissime modifiche è possibile scrivere la versione che valuta il massimo e il minimo di un array su valori in virgola mobile (float).

Continue reading Massimo e Minimo di un array in C

La mia prima applicazione scritta in Object-C e Cocoa: Circumference Calc

Probabilmente non l’ho ancora detto su Codeido, ma mi ritengo abbastanza esperto di programmazione in C (diciamo che ho una conoscenza e padronanza di 9/10 del linguaggio). Ho deciso così di buttarmi nell’apprendimento di un nuovo linguaggio, l’Objective-C, creato da Brad Cox alla metà degli anni ottanta presso la Stepstone Corporation. Adesso è il linguaggio di programmazione per eccellenza utilizzato nello sviluppo di applicazioni per Mac, iPhone e iPad e scelto da Apple. Inoltre, oltre all’apprendimento di questo linguaggio, in contemporanea mi cimenterò nell’uso del framework Cocoa sviluppato nei pressi di Cupertino. Penso che nessuno sviluppatore abbia mai documentato la sua “carriera” nell’apprendimento di un linguaggio (avanzato) come l’Object-C, che alla fine dei conti, è un miglioramento del C con l’aggiunta della programmazione OOP (Object Oriented Programming). Siccome il mio sogno personale è diventare a tutti gli effetti un esperto di questo linguaggio e successivamente distribuire qualche software, la prima cosa che si fa solitamente è iniziare con il solito “Hello World”. Non è stato questo il caso. Il libro a cui mi sono affidato per iniziare i miei studi è “Sviluppare applicazioni con Objective-C e Cocoa“, scritto da Tim Isted e recentemente tradotto in italiano, che mi è sembrato bene acquistare per via del suo approccio iniziale: non la solita pappardella sulla storia dell’informatica o un excursus base (fondamentale) del linguaggio C, ma un’approccio più pratico su questo nuovo linguaggio. Il primo capitolo? Si intitola “La prima applicazione” ed è quello che farete realmente, perché non si inizia da subito a sviluppare via codice, ma solo utilizzando Interface Builder (quindi tramite interfaccia grafica se così vogliamo chiamare questo approccio). Infine verrete addentrati sempre più nei meandri della programmazione Object-C. Mi è stato molto utile per capire la programmazione orientata agli oggetti, di cui non avevo pressoché nessuna infarinatura, e che nel momento in cui scrivo, non mi è stata ancora spiegata all’Università. Non ho ancora terminato il libro (sono ancora al 6° capitolo perché trovo fondamentale leggere, e nel frattempo provare con le proprie mani a strimpellare qualcosa sulla tastiera: è anche l’approccio consigliato dal libro), quindi ci saranno sicuramente altri articoli di questo genere sul sito (anzi, questo finirà sul blog) per farvi vedere come proseguono i miei studi del linguaggio.

Per il momento, vi “inciucio” la mia prima applicazione funzionante che ho riscritto ben 5 volte prima di non trovare errori. E’ veramente una stupidaggine (ed è proposta sul libro con tanto di spiegazione), ma la soddisfazione è tanta: è infatti il primo programma in assoluto che realizzo con un’interfaccia grafica perfettamente funzionale. Quindi, se la matematica NON è il vostro forte, forse potrebbe servivi il calcolo della circonferenza di un cerchio. 🙂 Apparte gli scherzi, eccola, funzionante (almeno sul mio MacBook Pro) e senza nessun apparente problema. Provatela e ditemi se inserendo il raggio tutto funziona come ci si aspetta. A proposito, evitate i commenti diffamatori, abbiate pietà di me 😀 uno studente va incoraggiato a fare sempre meglio, e prometto solennemente di impegnarmi al massimo. Ho tanti progetti in mente, e spero di poterli mostrare al grande pubblico il più presto possibile.

DOWNLOAD CircumCalc 0.1