<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mind Unpacked</title>
	<atom:link href="http://mindunpacked.com/feed/?paged=2" rel="self" type="application/rss+xml" />
	<link>http://mindunpacked.com</link>
	<description>informatica.elettronica.chimica.new stuff</description>
	<lastBuildDate>Tue, 22 Dec 2009 17:35:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<image>
<link>http://mindunpacked.com</link>
<url>http://mindunpacked.com/wp-content/plugins/maxblogpress-favicon/icons/favicon-2.ico</url>
<title>Mind Unpacked</title>
</image>
		<item>
		<title>Reti neurali attraverso algoritmi genetici in C++. Parte VI</title>
		<link>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-vi-ultima/</link>
		<comments>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-vi-ultima/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 17:57:53 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Intelligenza artificiale]]></category>
		<category><![CDATA[Reti neurali]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=345</guid>
		<description><![CDATA[Applicazioni.
Le reti neurali hanno diverse applicazioni e spaziano in diversi campi. In questo paragrafo elencherò alcune applicazioni interessanti che ho trovato sulla rete e poi mostrerò come è possibile creare un molto rudimentale sistema di riconoscimento dii  immagini, capace di riconoscere i numeri da 0 a 9.

Alcune applicazioni sono:
Vita artificiale: la vita artificiale tenta [...]]]></description>
			<content:encoded><![CDATA[<p align="center"><strong>Applicazioni.</strong></p>
<p align="justify">Le reti neurali hanno diverse applicazioni e spaziano in diversi campi. In questo paragrafo elencherò alcune applicazioni interessanti che ho trovato sulla rete e poi mostrerò come è possibile creare un molto rudimentale sistema di riconoscimento dii  immagini, capace di riconoscere i numeri da 0 a 9.</p>
<p><span id="more-345"></span></p>
<p align="justify">Alcune applicazioni sono:</p>
<p align="justify">Vita artificiale: la vita artificiale tenta di simulare l&#8217;evoluzione di organismi viventi tramite computer. Spesso gli organismi sono dotati di reti neurali per svolgere i loro compiti come trovare fonti di cibo, muoversi, etc&#8230;</p>
<p align="justify">Finanza: prevedere l&#8217;andamento dei mercati.</p>
<p align="justify">Riconoscimento di forme, immagini, facce, etc&#8230;</p>
<p align="justify">Quello che noi creeremo è un sistema molto rudimentale di riconoscimento delle immagini, di fatto potra riconoscere solo quelle immagini che gli abbiamo presentato nel training set e non sarà probabilmente in grado di riconoscerle se gli è stato modificato anche solamente qualche pixel. E&#8217; solo un esempio di base per mostrare cosa si può fare, ed anche in maniera abbastanza semplice. Le immagini che la nostra rete neurale sarà capace di riconoscere avranno dimensioni fisse (5&#215;7 pixels) e saranno simili a questa:</p>
<div id="attachment_346" class="wp-caption aligncenter" style="width: 108px"><a href="http://mindunpacked.com/wp-content/uploads/2008/12/1.png"><img class="size-medium wp-image-346" title="1" src="http://mindunpacked.com/wp-content/uploads/2008/12/1.png" alt="Immagine di esempio" width="98" height="138" /></a><p class="wp-caption-text">Immagine di esempio</p></div>
<p align="justify">
<p align="justify">
<p align="justify">
<p align="justify">I quadratini con il bordo nero sono semplicemente i pixel dell&#8217;immagine. Avendo questa immagine 7&#215;5 = 35 pixel in totale, la nostra rete neurale dovrà avere 35 neuroni di input, uno per ogni pixel. Per semplicità l&#8217;input potrà essere o 1 o 0, dove 1 simboleggia il colore rosso della precedente immagine e 0 lo sfondo. Così facendo si ottiene una matrice che rappresenta l&#8217;immagine, che nel caso di quella appena vista sarebbe questa:</p>
<p align="justify">
<p align="center">0 0 1 0 0</p>
<p align="center">0 1 1 0 0</p>
<p align="center">0 0 1 0 0</p>
<p align="center">0 0 1 0 0</p>
<p align="center">0 0 1 0 0</p>
<p align="center">0 0 1 0 0</p>
<p align="center">0 1 1 1 0</p>
<p align="center">
<p align="justify">Nell&#8217;allenamento della nostra rete, noi daremo un solo esempio per ogni numero, ma volendo potremmo dare più esempi diversi che rappresentano diversi modi di scrivere il numero 1 e così la nostra rete avrebbe una capacità più alta di riconoscere caratteri diversi (chiaramente l&#8217;allenamento sarà più lungo).</p>
<p align="justify">Per la nostra rete neurale creeremo noi il training set direttamente su un file di testo o altrimenti, essendo la rete neurale capace di riceve in input solo dei numeri, dovremmo creare un programma che data in input un&#8217;immagine crei la matrice numerica associata ad essa, ma siccome il nostro training set sarà molto piccolo le creeremo manualmente. Ogni riga dovrà contenere la rappresentazione di un numero, di conseguenza non avremo matrici nel file di input ma le righe saranno affiancate. Il file di input risulta così:</p>
<p align="justify">
<p style="text-align: center;">0 0 1 0 0 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 0 0 1 0 0</p>
<p style="text-align: center;">0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1 0</p>
<p style="text-align: center;">0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 1 1 1 1</p>
<p style="text-align: center;">0 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0 0 1 1 0</p>
<p style="text-align: center;">0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 1 0 0 0 1 0 0 0 0 1 0</p>
<p style="text-align: center;">0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0</p>
<p style="text-align: center;">0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 0 1 1 1 0</p>
<p style="text-align: center;">0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0</p>
<p style="text-align: center;">0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 0 1 1 1 0</p>
<p style="text-align: center;">0 1 1 1 0 1 0 0 0 1 1 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0</p>
<p style="text-align: center;">
<p align="justify">Se spezzate ogni riga in parti composte da 5 elementi riottenete la matrice che rapresenta il numero.</p>
<p align="justify">Il file di output avrà tante righe quante quelle del file di input e sarà il seguente:</p>
<p align="justify">
<p style="text-align: center;">1 0 0 0 0 0 0 0 0 0</p>
<p style="text-align: center;">0 1 0 0 0 0 0 0 0 0</p>
<p style="text-align: center;">0 0 1 0 0 0 0 0 0 0</p>
<p style="text-align: center;">0 0 0 1 0 0 0 0 0 0</p>
<p style="text-align: center;">0 0 0 0 1 0 0 0 0 0</p>
<p style="text-align: center;">0 0 0 0 0 1 0 0 0 0</p>
<p style="text-align: center;">0 0 0 0 0 0 1 0 0 0</p>
<p style="text-align: center;">0 0 0 0 0 0 0 1 0 0</p>
<p style="text-align: center;">0 0 0 0 0 0 0 0 1 0</p>
<p style="text-align: center;">0 0 0 0 0 0 0 0 0 1</p>
<p><center><script type="text/javascript">
heyos_ad_user = 11334;
heyos_ad_type = "G";
heyos_ad_format = "1";
heyos_color_border = "23292b";
heyos_color_bg = "23292b";
heyos_color_link = "FFFFFF";
heyos_color_text = "21b8ca";
heyos_color_url = "21b8ca";
</script>
<script type="text/javascript" src="http://admaster.heyos.com/core/bnr.js"></script></center></p>
<p align="justify">I neuroni di output saranno 10 ed ognuno è associato ad un numero. Con il numero 0 il primo neurone emette un segnale mentre gli altri no, con il numero 1 il secondo neurone emette un segnale mentre gli altri no, etc&#8230; di conseguenza ci aspettiamo che dopo l&#8217;addestramento, quando passiamo in input, per esempio il numero 9 soltanto l&#8217;ultimo neurone si attiverà. Il codice è il seguente:</p>
<pre class="brush: cpp;">
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;sstream&gt;
#include &lt;vector&gt;
#include &lt;ctime&gt;
#include &lt;cmath&gt;

using namespace std;

#include &quot;Misc.hpp
#include &quot;GenAlg.hpp&quot;
#include &quot;NeuralNet.hpp&quot;
#include &quot;NNController.hpp&quot;

int main() {
NNController NC(35, 10, 1, 10);
NC.loadTrainingSet(&quot;input&quot;, &quot;output&quot;);
NC.train();
NC.saveWeights(&quot;img.txt&quot;);
cout &lt;&lt; &quot;*** La rete e' allenata ***&quot; &lt;&lt; endl;
}
</pre>
<p align="justify">Come vedete, abbiamo creato 35 neuroni di input, 10 di output ed un livello nacosto con 10 neuroni.</p>
<p align="center"><strong>LINKS</strong></p>
<p align="justify"><a href="http://www.ai-junkie.com/ann/evolved/nnt1.html">http://www.ai-junkie.com/ann/evolved/nnt1.html</a> &#8211; Questo tutorial in Inglese sulle reti neurali è uno dei migliori che abbia mai letto, tant&#8217;è che ne ho preso spunto per scrivere questo. Vengono usati anche lì gli algoritmi genetici per aggiornare la rete e troverete delle somiglianze anche nelle classi del codice (però vi assicuro che il codice per questo tutorial l&#8217;ho scritto da zero <img src='http://mindunpacked.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://www.ai-junkie.com/ga/intro/gat1.html">http://www.ai-junkie.com/ga/intro/gat1.html</a> &#8211; Tutorial sugli algoritmi genetici, sempre in Inglese.</p>
<p><a href="http://blacklight.gotdns.org/wiki/index.php/Introduzione_ai_sistemi_fuzzy_e_alle_reti_neurali">http://blacklight.gotdns.org/wiki/index.php/Introduzione_ai_sistemi_fuzzy_e_alle_reti_neurali</a> &#8211; Implementazione di una rete neurale error back propagation in C, tutorial in Italiano.</p>
<p align="justify"><a href="http://www.aitalk.net/">http://www.aitalk.net</a> &#8211; Forum sull&#8217;intelligenza artificiale in lingua Inglese. Contiene anche una piccola sezione in lingua Italiana.</p>
<p>Ho anche realizzato la stessa guida in formato PDF: trovate <a href="http://www.mindunpacked.com/risorse/TutorialRetiNeurali.tar.gz">QUI</a> un archivio contenente tutti i file sorgente di cui abbiamo parlato e la guida in formato PDF (un po meglio impaginata e con qualche illustrazione in piu&#8217;).<br />
Alla prossi</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-vi-ultima/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PETN (Tetranitrato di pentaeritrite)</title>
		<link>http://mindunpacked.com/2008/petn-tetranitrato-di-pentaeritrite/</link>
		<comments>http://mindunpacked.com/2008/petn-tetranitrato-di-pentaeritrite/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 16:54:13 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Chimica]]></category>
		<category><![CDATA[esplosivo]]></category>
		<category><![CDATA[nitrazione]]></category>
		<category><![CDATA[PETN]]></category>
		<category><![CDATA[sintesi]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=337</guid>
		<description><![CDATA[Il PETN (Tetranitrato di pentaerite, anche conosciuto come pentrite o pentaeritritolo tetranitrato) è uno degli esplosivi più potenti conosciuti, con fattore relativo di efficacia (fattore R.E.) di 1.66. Esso è più sensibile agli shock o alla frizione del TNT. È l&#8217;ingrediente che sta alla base dell&#8217;esplosivo plastico Semtex.
Viene anche usato come vasodilatatore, similmente al trinitrato [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Il <strong>PETN</strong> (Tetranitrato di pentaerite, anche conosciuto come pentrite o pentaeritritolo tetranitrato) è uno degli esplosivi più potenti conosciuti, con fattore relativo di efficacia (fattore R.E.) di 1.66. Esso è più sensibile agli shock o alla frizione del TNT. È l&#8217;ingrediente che sta alla base dell&#8217;esplosivo plastico Semtex.<br />
Viene anche usato come vasodilatatore, similmente al trinitrato di glicerina (nitroglicerina). Una medicina usata per le malattie cardiache, il Lentonitrat, è costituita da PETN puro.<span id="more-337"></span><br />
<center><br />
<table style="height: 266px;" border="0" cellspacing="0" cellpadding="0" width="555">
<tbody>
<tr>
<td>
<p><div class="wp-caption aligncenter" style="width: 210px"><img title="PETN - Molecola animata" src="http://mindunpacked.com/risorse/petn.gif" alt="PETN - Molecola animata" width="200" height="200" /><p class="wp-caption-text">PETN - Molecola animata</p></div></td>
<td style="text-align: justify; padding-left: 90px;">Questo esplosivo si presenta sotto forma di solido cristallino bianco ed inodore. La velocità di detonazione del PETN alla densità di 1.7 g/cm3 è di 8,400 m/s. Il calore prodotto dall&#8217;esplosione è di 5,862 kj per chilogrammo, o una volta e mezza quello prodotto dal TNT. La formula bruta del PETN è C(CH<sub>2</sub>ONO<sub>2</sub>)<sub>4</sub>, con una densità teorica massima dei cristalli di 1.773 g/cm3. Fonde alla temperatura di 141° C, con una temperatura di auto-ignezione di 190 °C.</td>
</tr>
</tbody>
</table>
<p></center><br />
<center><script type="text/javascript">
heyos_ad_user = 11334;
heyos_ad_type = "G";
heyos_ad_format = "1";
heyos_color_border = "23292b";
heyos_color_bg = "23292b";
heyos_color_link = "FFFFFF";
heyos_color_text = "21b8ca";
heyos_color_url = "21b8ca";
</script>
<script type="text/javascript" src="http://admaster.heyos.com/core/bnr.js"></script></center><br />
<strong>Sintesi</strong></p>
<p style="text-align: justify;">La preparazione della pentrite comporta la nitrazione della pentaeritrite con una mistura concentrata di acido nitrico e solforico. Il metodo migliore è tuttavia quello di utilizzare solamente acido nitrico molto concentrato (98%+), visto che l&#8217;utilizzo di una mistura di acidi potrebbe creare dei sottoprodotti instabili. Avviene la seguente reazione:</p>
<dl>
<dd style="margin-bottom: 0.5cm;">C(CH<sub>2</sub>OH)<sub>4</sub> + 	4HNO<sub>3</sub> → C(CH<sub>2</sub>ONO<sub>2</sub>)<sub>4</sub> + 	4H<sub>2</sub>O </dd>
</dl>
<p><strong>Reagenti e Materiali</strong></p>
<ul>
<li>
<p style="margin-bottom: 0cm;">Acido solforico concentrato al 98% 	(H2So4)</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Acido nitrico concentrato al 65% 	(HNO3)</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Pentaeritrite</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Acetone</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Acqua distillata</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Bicarbonato di sodio (NaHCO3)</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Due becker puliti</p>
</li>
<li>
<p style="margin-bottom: 0.5cm;">Una pipetta</p>
</li>
</ul>
<p><strong>Procedimento</strong></p>
<ul>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">Viene preparato un bagno di acqua 	fredda per raffreddare un becker contenete 34 ml di acido nitrico. 	24,8ml di acido solforico vengono messi lentamente con una pipetta 	nel becker contenete l&#8217;acido nitrico. La miscela produrrà molto 	calore, e sarà necessario aggiungere del ghiaccio e del sale nel 	bagno d&#8217;acqua fredda in cui sta immerso il becker.</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">Viene ora preparato un secondo 	bagno d&#8217;acqua fredda/ghiaccio da usare in caso di emergenza se la 	temperatura del becker dovesse salire troppo.</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">Con la miscela di acidi, 	precedentemente creata, alla temperatura di circa -25° C, vengono 	aggiunti 10g di pentaeritrite, 2g alla volta. È importante 	mescolare la miscela durate l&#8217;aggiunta del composto. A nitrazione 	terminata, la temperatura comincerà a scendere, e la mistura 	acquisterà una certa densità. Una bassa temperatura iniziale è la 	chiave per una buona sintesi. La temperatura non deve in nessun caso 	superare gli 0° C. Se vengono a formarsi dei fumi rosso/marroni 	(N2O4 / NO2 ), significa che il miscuglio è ad una temperatura 	troppo alta, e necessita di essere subito raffreddato.</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">Il composto viene mescolato per 	altri 10 minuti, dopo l&#8217;aggiunta di tutto il pentaeritrite. La 	mistura vine allora messa in un bagno di acqua calda a 45° C per 25 	minuti. Questo consentirà di aumentare la quantità di PETN finale. 	È importate mantenere la temperatura a 45° C senza andare oltre, 	continuando a mescolare.</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">La mistura viene diluita con 450ml 	di acqua fredda (0-1°C) e l&#8217;eccesso di acqua successivamente 	decantato dopo che i cristalli si saranno depositati sul fondo. La 	mistura deve essere aggiunta lentamente all&#8217;acqua calda, in quanto 	un eccesso di acido solforico può provocare un innalzamento della 	temperatura, che potrebbe portare ad una decomposizione del prodotto 	finale</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">Il PETN viene filtrato e lavato 	con acqua fredda, e quindi neutralizzato con una soluzione calda di 	bicarbonato di sodio.</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">200ml di acetone vengono 	riscaldati a 50°C, ed il PETN vine mescolato al suo interno finché 	sarà completamente dissolto (Solubilità: 58g/100ml di acetone a 	50° C). Asciugare il PETN prima di questo passaggio, richiederà 	meno acetone.</p>
</li>
<li>
<p style="margin-bottom: 0.5cm; text-align: justify;">La mistura di PETN e acetone 	viene filtrata e posta in un becker contenete 600ml di 	acqua/ghiaccio tritato, che farà precipitare il PETN sul fondo 	sotto forma di cristalli. La soluzione viene filtrata ottenendo i 	cristalli di PETN. Quest&#8217;ultimo viene poi lasciato asciugare. Si 	otterranno circa 22g di prodotto con una rendita del 91% circa.</p>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/petn-tetranitrato-di-pentaeritrite/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Steganografia in C++</title>
		<link>http://mindunpacked.com/2008/steganografia-in-c/</link>
		<comments>http://mindunpacked.com/2008/steganografia-in-c/#comments</comments>
		<pubDate>Sun, 28 Dec 2008 19:13:21 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[LSB]]></category>
		<category><![CDATA[Steganografia]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=321</guid>
		<description><![CDATA[Su Mind Unpacked abbiamo gia&#8217; parlato di steganografia digitale in due precedenti articoli (Introduzione alla steganografia digitale e Algoritmi steganografici), oggi percio&#8217; discuteremo di un&#8217;implementazione in C++ dell&#8217;algoritmo LSB. L&#8217;algoritmo e&#8217; gia&#8217; stato trattato dal punto di vista teorico nei precedenti articoli, quindi non mi soffermero&#8217; piu&#8217; di tanto su di esso e passero&#8217; quasi [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">Su Mind Unpacked abbiamo gia&#8217; parlato di <strong>steganografia</strong> digitale in due precedenti articoli (<a title="Introduzione alla steganografia digitale" href="http://mindunpacked.com/2008/introduzione-alla-steganografia-digitale/" target="_blank">Introduzione alla steganografia digitale</a> e <a title="Algoritmi steganografici" href="http://mindunpacked.com/2008/algoritmi-steganografici/" target="_blank">Algoritmi steganografici</a>), oggi percio&#8217; discuteremo di un&#8217;<strong>implementazione in C++ dell&#8217;algoritmo LSB</strong>. L&#8217;algoritmo e&#8217; gia&#8217; stato trattato dal punto di vista teorico nei precedenti articoli, quindi non mi soffermero&#8217; piu&#8217; di tanto su di esso e passero&#8217; quasi subito alla spiegazione del codice.</p>
<p><span id="more-321"></span></p>
<p style="text-align: justify">L&#8217;algoritmo <strong>LSB</strong> (least significat bit) mira a nascondere un messaggio in un contenitore (immagine, file audiom file video) modificando i bit meno significativi. Nel nostro caso creeremo un programma per <strong>nascondere file di testo all&#8217;interno di immagin</strong><strong>i</strong> bitmap. Ogni pixel della nostra immagine e&#8217; rappresentato da una terna di numeri che indicano le tre componenti RGB. Modificheremo il bit meno significativo di ogni componente di ogni pixel e lo adatteremo ai bit del nostro messaggio di testo. Il cambiamento che otteremo modificando solo il bit meno significativo sara&#8217; al massimo di una unita&#8217; e, di conseguenza, produrra&#8217; immagini all&#8217;apparenza identiche, poiche&#8217; un tale cambiamento non e&#8217; percepibile ad occhio nudo.</p>
<p style="text-align: justify">Il nostro programma e&#8217; sostanzialmente diviso in due parti: quella per nascondere il testo nell&#8217;immagine e quella per recuperarlo.</p>
<p style="text-align: justify"><strong>Steganografare un testo</strong></p>
<p style="text-align: justify">La prima parte del programma si occupera&#8217; di fare le seguenti operazioni:</p>
<ol>
<li style="text-align: justify">Leggere il messaggio da un file di testo</li>
<li>Calcolare il numero di pixels necessari ad occultare il messaggio nell&#8217;immagine ed accertarsi che l&#8217;immagine sia abbastanza grande da poterlo fare. Salvare in forma binaria il valore di ogni componente di questi pixels.</li>
<li>Modificare i bit meno significativi per adattarli a quelli del messaggio</li>
<li>Scrivere i nuovi bit su una nuova immagine apparentemente uguale alla prima, ma contenente il testo.</li>
</ol>
<p>Saltando il passo 1 (che spero chiunque sia capace di fare), passiamo al due:</p>
<pre class="brush: cpp;">
numbits = message.size()*8;  // La stringa message contiene il messaggio letto dal file
numpixels = (numbits%3 == 0 ? numbits/3 : (int)numbits/3 + 1);
numrows = (int)numpixels/img.TellWidth() + 1;
if (numrows &gt; img.TellHeight()) {
	cout &lt;&lt; &quot;Errore: il messaggio e' troppo lungo per essere contenuto in questa immagine.&quot; &lt;&lt; endl;
	exit(0);
}
for (int i = 0; i &lt; numrows; i++) {
	for (int j = 0; j &lt; img.TellWidth(); j++) {
		bits.push_back(bitset&lt;8&gt;((int)img(j, i)-&gt;Red));
		bits.push_back(bitset&lt;8&gt;((int)img(j, i)-&gt;Green));
		bits.push_back(bitset&lt;8&gt;((int)img(j, i)-&gt;Blue));
	}
}
</pre>
<p><!--adsense--></p>
<p>Il programma calcola il numero di bit e il numero di pixel necessari in base alla lunghezza del messaggio. Visto che ogni pixel puo&#8217; nascondere 3 bit, il numero di pixel viene calcolato semplicemente dividendo il numero di bit per 3 e arrotondando per eccesso nel caso di resto. numrows contiene invece il numero di righe dell&#8217;immagine che bisogna copiare in memoria. Se il numero di righe e&#8217; maggiore dell&#8217;altezza del&#8217;immagine il programma genera un errore poiche&#8217; l&#8217;immagine e&#8217; troppo piccola per contenere il messaggio. Dopo aver fatto cio&#8217;, salviamo i tutti i valori RGB dei pixel che ci servono in un array di bitset. bits e&#8217; un vettore (classe vector delle STL) di oggetti bitset, una classe della STL creata appositamente per gestire dati in forma binaria. La notazione bitset&lt;8&gt;(&#8230;) crea un oggetto bitset con 8 bit che assumono il valore dell&#8217;argomento che gli si passa tra parentesi. Visto che i valori RGB di un&#8217;immagine sono compresi tra 0 e 255 8 bit sono sufficienti.</p>
<pre class="brush: cpp;">
count = 0;
for (int i = 0; i &lt; message.size(); i++) {
	bitset&lt;8&gt; temp = bitset&lt;8&gt;(message[i]);
	for (int b = 7; b &gt;= 0; b--) {
		bits[count].set(0, temp[b]); // 0 e' l'indice del bit meno significativo; 		temp[b] e' il b-esimo bit della lettera che stiamo esaminando
		count++;
	}
}
</pre>
<p>Dopo aver salvato i valori in memoria, dobbiamo modificare il bit meno significativo di ogni elemento salvato per renderlo uguale a quello del nostro messaggio. Il codice qui sopra svolge questo compito: scorre ogni lettera del messaggio e crea un oggetto bitset contenente il valore di quella lettera in binario. Il ciclo innestato scorre tutti i bit della lettera e modifica i bit meno significativi dell&#8217;immagine in modo appropriato.</p>
<pre class="brush: cpp;">
for (int i = 0; i &lt; numrows; i++) {
	for (int j = 0; j &lt; img.TellWidth(); j++) {
		imgout(j, i)-&gt;Red = (int)bits[count++].to_ulong();
		imgout(j, i)-&gt;Green = (int)bits[count++].to_ulong();
		imgout(j, i)-&gt;Blue = (int)bits[count++].to_ulong();
	}
}
for (int i = numrows; i &lt; img.TellHeight(); i++) {
	for (int j = 0; j &lt; img.TellWidth(); j++) {
		imgout(j, i)-&gt;Red = img(j, i)-&gt;Red;
		imgout(j, i)-&gt;Green = img(j, i)-&gt;Green;
		imgout(j, i)-&gt;Blue = img(j, i)-&gt;Blue;
	}
}
imgout.WriteToFile(&quot;out.bmp&quot;);
</pre>
<p><!--adsense--></p>
<p>Una volta che i bit sono stati modificati in maniera corretta, dobbiamo solo riscriverli su una nuova immagine. Il primo ciclo scrive i bit contenenti il messaggio (la funzione to_ulong() converte un bitset nel suo valore decimale), mentre il secondo riscrive semplicemente i valori dei pixel che non sono stati modificati riprendendoli dall&#8217;immagine originale.</p>
<p><strong>Recuperare il testo steganografato</strong></p>
<p>La seconda parte del programma e&#8217; quella che, data in input un&#8217;immagine recupera il testo contenuto in essa. Un difetto del programma e&#8217; quello di richiedere la lunghezza del messaggio per poterlo estrarre: in realta&#8217; si potrebbe ovviare a questo problema in maniera piuttosto semplice (dopo vedremo come) ma per ora, bisognera&#8217; accontentarsi di andare a tentativi se non si conosce la lunghezza del messaggio completo.</p>
<p>La struttura di questa seconda parte ricalca quella della prima: dopo aver preso in input la lunghezza del messaggio ed aver calcolato in base ad essa il numero di pixel che sono stati modificati, il programma prende dall&#8217;immagine i valori delle componenti di questi pixel e li mette in un array di bitset. Un secondo ciclo:</p>
<pre class="brush: cpp;">
for (int i = 1; i &lt; numbits; i++) {
	temp.set(count, bits[i-1][0]);
	count--;
	if (count == -1) {
		count = 7;
		cout &lt;&lt; (char)temp.to_ulong();
	}
}
</pre>
<p>si occupa di prendere i bit meno significativi a gruppi di 8 e di stampare il corrispondente valore alfanumerico.</p>
<p><strong>Possibili miglioramenti</strong></p>
<p>Il programma in questa maniera e&#8217; piuttosto rudimentale, ecco alcuni possibili miglioramenti che potreste allenarvi a mettere in pratica:</p>
<ol>
<li>Evitare di dover richiedere la lunghezza quando bisogna estrarre un messaggio. Una possibilita&#8217; potrebbe essere quella di conservare i primi N bit meno significativi dell&#8217;immagine per salvare la lunghezza del messaggio e per estrarla al volo senza doverla richiedere all&#8217;utente. 10 bit permetterebbero, per esempio, di salvare un numero fino a 2<sup>10</sup> = 1024.</li>
<li>Introdurre la possibilita&#8217; di inserire una chiave. Una chiave potrebbe essere un numero intero N che indicherebbe al programma di modificare non tutti i pixel uno per uno ma di prendere 1 pixel ogni N. Questo ridurrebbe la capacita&#8217; dell&#8217;immagine di contenere messaggi ma renderebbe piu&#8217; difficile un&#8217;eventuale individuazione del messaggio.</li>
<li>Introdurre la possibilita&#8217; di crittografare un messaggio prima di steganografarlo per una maggiore sicurezza.</li>
</ol>
<p>Ecco il codice del programma: <a href="../../risorse/Stego.zip">Steganografia in C++</a>. Fa uso delle librerie EasyBMP per la gestione delle immagini presenti nell&#8217;archivio stesso.</p>
<p>Ciao!</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/steganografia-in-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Generatore di onde triangolari</title>
		<link>http://mindunpacked.com/2008/generatore-onde-triangolari/</link>
		<comments>http://mindunpacked.com/2008/generatore-onde-triangolari/#comments</comments>
		<pubDate>Fri, 19 Dec 2008 16:07:59 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Elettronica]]></category>
		<category><![CDATA[bassa frequenza]]></category>
		<category><![CDATA[BF]]></category>
		<category><![CDATA[Generatore]]></category>
		<category><![CDATA[onde triangolari]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=305</guid>
		<description><![CDATA[Vi presento uno schema di un generatore di onde triangolari. Come molti sapranno queste onde sono più utili di quelle sinusoidali per controllare stadi di BF in amplificatori Hi-Fi. Tale progetto può inoltre essere utilizzato come semplice e preciso oscillatore di BF.
Il circuito presenta un solo integrato di tipo MC.1458, o in alternativa un LM.358, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Vi presento uno schema di un <strong>generatore di onde triangolari</strong>. Come molti sapranno queste onde sono più utili di quelle sinusoidali per controllare stadi di BF in amplificatori Hi-Fi. Tale progetto può inoltre essere utilizzato come semplice e preciso oscillatore di BF.<span id="more-305"></span><br />
Il circuito presenta un solo integrato di tipo MC.1458, o in alternativa un LM.358, il quale contiene al suo interno due amplificatori operazionali di tipo uA.741, quindi è possibile raggiungere gli stessi risultati anche con due uA.741 singoli. Il primo di questi amplificatori operazionali viene sfruttato per generare un segnale ad onda quadra, mentre il secondo funge da integratore per trasformare le onde quadre in onde triangolari. Il trimmer da 1 megaohm non serve, come si potrebbe supporre, per modificare la frequenza dell&#8217;onda ma bensì per linearizzare quest&#8217;ultima. Per modificare la frequenza è necessario agire sul potenziometro R4, e contemporaneamente sul deviatore S1. In linea di massima la frequenza può variare da un minimo di 5 hz ad un massimo di 10 khz. Ecco a voi lo schema.<br />
<!--adsense--><br />
<center><br />
<table style="height: 16px;" border="0" cellspacing="0" cellpadding="0" width="596">
<tbody>
<tr>
<td>
<p><div id="attachment_306" class="wp-caption aligncenter" style="width: 310px"><a href="http://mindunpacked.com/wp-content/uploads/2008/12/onde_triangolari.gif"><img class="size-medium wp-image-306" title="onde_triangolari" src="http://mindunpacked.com/wp-content/uploads/2008/12/onde_triangolari-300x200.gif" alt="Schema generatore di onde triangolari" width="300" height="200" /></a><p class="wp-caption-text">Schema generatore di onde triangolari</p></div></td>
<td>
<p style="margin-bottom: 0cm; padding-left: 30px; text-align: left;">R1: 10.000 ohm<br />
R2: trimmer da 1 megaohm<br />
R3: 8.200 ohm<br />
R4:  22.000 ohm potenziomentro<br />
R5: 1.500 ohm<br />
R6: 47.000 ohm<br />
C1: 10 mF elettrolitico<br />
C2: 2.200  pF poliestere<br />
C3: 22.000 pF poliestere<br />
C4:  220.000 pF poliestere<br />
C5: 10 mF elettrolitico 16 volt<br />
IC1: integrato MC1458 o LM358</td>
</tr>
</tbody>
</table>
<p></center></p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/generatore-onde-triangolari/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Animare il Buddhabrot</title>
		<link>http://mindunpacked.com/2008/animare-il-buddhabrot/</link>
		<comments>http://mindunpacked.com/2008/animare-il-buddhabrot/#comments</comments>
		<pubDate>Wed, 17 Dec 2008 16:55:53 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Buddhabrot]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Frattali]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=244</guid>
		<description><![CDATA[In un precedente articolo abbiamo visto come sia possibile renderizzare immagini dell&#8217;insieme di Mandelbrot ottenendo il cosiddetto Buddhabrot. Oggi mostrerò come si possano renderizzare, invece, delle animazioni del Buddhabrot sfruttando il fatto che questo frattale puo&#8217; essere &#8220;interpretato&#8221; come un oggetto in quattro dimensioni. Spiegare cio&#8217; non e&#8217; molto facile, per il semplice motivo che [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">In un <a title="Renderizzare il Buddhabrot" href="http://mindunpacked.com/2008/un-nuovo-metodo-per-visualizzare-linsieme-di-mandelbrot-il-buddhabrot/" target="_self">precedente articolo</a> abbiamo visto come sia possibile renderizzare immagini dell&#8217;insieme di Mandelbrot ottenendo il cosiddetto <strong>Buddhabrot</strong>. Oggi mostrerò come si possano renderizzare, invece, delle <strong>animazioni del Buddhabrot</strong> sfruttando il fatto che questo frattale puo&#8217; essere &#8220;interpretato&#8221; come un oggetto in quattro dimensioni. Spiegare cio&#8217; non e&#8217; molto facile, per il semplice motivo che non ci e&#8217; possibile visualizzare un oggetto in 4 dimensioni e che dobbiamo accontentarci di una approssimazione creata dalla nostra immaginazione, ma faro&#8217; del mio meglio per rendere l&#8217;articolo il piu&#8217; chiaro possibile.<br />
<span id="more-244"></span><br />
Il concetto di base e&#8217; questo: quando utilizziamo la formula di Mandelbrot e cioe&#8217; Z<sub>n+1</sub>=Z<sub>n</sub><sup>2</sup> + C i valori che entrano in gioco sono 4 e sono le parti reali di Z e C e le loro parti immaginarie (d&#8217;ora in poi saranno indicate con Z.r, C.r, Z.i, C.i); per ogni possibile combinazione di questi quattro valori avremo un solo valore in uscita, diverso per ogni combinazione. Visto pero&#8217;, che non possiamo visualizzare un oggetto in quattro dimensioni, l&#8217;unica cosa che possiamo fare e&#8217; visualizzare una sezione bidimensionale dell&#8217;oggetto, ed e&#8217; questo quello che accade quando poniamo Z=0 nel renderizzare l&#8217;insieme di Mandelbrot. Gli insieme di Julia non sono altro che sezioni dello stesso oggetto ma su piani diversi (che corrispondono ad una diversa scelta del valore iniziale di Z).</p>
<p style="text-align: justify;">In un ambiente tridimensionale abbiamo 3 piani perpendicolari tra di loro; in <strong>4 dimensioni</strong> invece, questi piani diventano 6 e sono rappresentati appunto dalle varie coppie possibili dei 4 valori in entrata: [Z.r, Z.i], [Z.r, C.r], [Z.r, C.i], [Z.i, C.r], [Z.i, C.i], [C.r, C.i]. Questi piani sono tutti perpendicolari tra di loro e sono i piani che si riconoscono a prima vista, ma ovviamente il numero di piani su cui potremmo effettuare delle sezioni da visualizzare e&#8217; infinito. Questo e&#8217; il punto che ci permette di renderizzare delle vere e proprie animazioni che includono delle <strong>rotazioni del Buddhabrot</strong>. Prima di parlare di questo, pero&#8217;, vediamo quali sono le modifiche da effettuare al file sorgente che ho distribuito nel precedente articolo per renderizzare sezioni di piani diverse.</p>
<p style="text-align: justify;">In realta&#8217;, la modifica da fare e&#8217; una sola ed e&#8217; questa: nella funzione escape() si trova questa parte:</p>
<pre class="brush: cpp;">
zz[(int)N].r = ZOOM*(Z.r+OFFSET_X)*(WIDTH/2);
zz[(int)N].i = ZOOM*(Z.i)*(HEIGHT/2) + HEIGHT/2;
</pre>
<p style="text-align: justify;">Come vedete, le coordinate che prendiamo in considerazione sono Z.r e Z.i. Basta cambiare questi valori per renderizzare un&#8217;altra sezione del frattale. Se al posto di Z.i mettiamo, per esempio, C.r, visualizzeremo l&#8217;oggetto visto dal piano [Z.r, C.r].</p>
<p style="text-align: justify;">Vediamo ora come realizzare una rotazione del frattale. Quello che vogliamo fare e&#8217;, in poche parole, passare gradualmente dall&#8217;immagine di un piano, diciamo [Z.r, Z.i] a quella di un&#8217;altro, per esempio, [Z.i, C.r]. Per fare cio&#8217; dobbiamo modificare sempre la formula precedente, nella seguente maniera:</p>
<pre class="brush: cpp;">
zz[(int)N].r = ZOOM*(rot*Z.r+Z.i*(1-rot)+OFFSET_X)*(WIDTH/2);
zz[(int)N].i = ZOOM*(rot*Z.i+C.r*(1-rot))*(HEIGHT/2) + HEIGHT/2;
</pre>
<p><!--adsense--></p>
<p style="text-align: justify">E&#8217; apparso un nuovo coefficiente, rot. Questo, come potete immaginare, e&#8217; un coefficiente che rappresenta, se vogliamo, l&#8217;angolo di rotazione. Per un valore di rot pari a 1, verra&#8217; renderizzato il piano [Z.r, Z.i] poiche&#8217; 1-rot = 0 e quindi le parti Z.i e C.r si annullano. Per rot = 0, avverra&#8217; il contrario. Ovviamente per valori di rot che variano tra 0 e 1 otteremo immagini diverse, per esempio, visto che la rotazione complessiva e&#8217; di 90° (da rot = 0 a rot = 1), rot=0.5 dovrebbe corrispondere ad una rotazione di 45°. Se si renderizzano varie immagini per valori di rot che aumentano progressivamente da 0 a 1, si otterra&#8217; una vera e propria animazione del Buddhabrot rotante.</p>
<p style="text-align: justify">Ora, se non volete mettervi a modificare manualmente ogni volta il valore di rot, vi conviene aggiungere un paio di cicli for al codice e fare in modo che, ad ogni ciclo, il valore di rot venga modificato per renderizzare un&#8217;immagine diversa. Ecco un esempio di &#8220;rotazione&#8221;, anche se non appare affatto come tale:</p>
<p style="text-align: center"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/NcyQHsuv-1o&amp;hl=it&amp;fs=1" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/NcyQHsuv-1o&amp;hl=it&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p style="text-align: justify">Vi lascio un ultimo link alla pagina originale creata da chi ha scoperto questa tecnica (e&#8217; in inglese): <a title="Buddhabrot Hologram" href="http://www.superliminal.com/fractals/bgram/ZrZiOut.htm" target="_blank">http://www.superliminal.com/fractals/bgram/ZrZiOut.htm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/animare-il-buddhabrot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lactucina e lactucarium</title>
		<link>http://mindunpacked.com/2008/lactucina-e-lactucarium/</link>
		<comments>http://mindunpacked.com/2008/lactucina-e-lactucarium/#comments</comments>
		<pubDate>Wed, 17 Dec 2008 12:30:01 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Chimica]]></category>
		<category><![CDATA[estrazione]]></category>
		<category><![CDATA[lactuca virosa]]></category>
		<category><![CDATA[lactucarium]]></category>
		<category><![CDATA[lactucina]]></category>
		<category><![CDATA[oppio di lattuga]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=284</guid>
		<description><![CDATA[La lactucina (C11H14O4) è un composto organico presente in molte varietà di lattuga, con percentuali più o meno alte. Allo stato puro si presenta sotto forma di cristalli bianchi di forma romboide, inodore, neutra e dal sapore amaro. Gli effetti sull&#8217;organismo sono prevalentemente di tipo sedativo, molto simili a quelli dei principali oppiacei. I primi [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm;" align="justify">La <strong>lactucina</strong> (C11H14O4) è un composto organico presente in molte varietà di lattuga, con percentuali più o meno alte. Allo stato puro si presenta sotto forma di cristalli bianchi di forma romboide, inodore, neutra e dal sapore amaro. Gli effetti sull&#8217;organismo sono prevalentemente di tipo sedativo, molto simili a quelli dei principali oppiacei. I primi effetti analgesici si manifestano con dosi tra i 15 ed i 30 mg/kg, risultando simile – su questo frangente – all&#8217;ibuprofene.<span id="more-284"></span><br />
<!--adsense--><br />
La lactucina è presente soprattutto nel <strong>lactucarium</strong>, chiamato anche oppio di lattuga, il quale viene estratto dalla <strong>Lactuca Virosa</strong> (o anche dalla cicoria &#8211; Cichorium intybus -, ma più raramente), ed ha l&#8217;aspetto dell&#8217;oppio, infatti la consistenza, il sapore ed il profumo sono praticamente i medesimi. In alcune occasioni viene, ma soprattutto veniva, usato come sostituto dell&#8217;oppio proprio perché presenta degli effetti simili a quest&#8217;ultimo, malgrado in forma più blanda. Inoltre non sembra creare dipendenza.<br />
Come detto in precedenza, la pianta più comune per estrarre il lactucarium, è la Lactuca Virosa, una pianta decisamente comune, di tipo annuale, che cresce soprattutto in luoghi aridi e ghiaiosi. Può raggiungere altezze considerevoli, anche oltre un metro crescendo su di un unico stelo. Essa contiene un fluido bianco appiccicoso ed amaro sia nello stelo che nelle foglie, che una volta essiccato può essere utilizzato per scopi medici – vedi proprietà sopra descritte. Oltre alla lactucina sono presenti anche altre sostanze, tra cui: <em>lactupicrina,</em> <em>acido lactucico</em>, e discrete quantità di <em>lactucerina</em>. <a href="http://mindunpacked.com/risorse/lactuca_components.jpeg">(qui un elenco delle altre sostanze contenute della pianta)</a><br />
<center><br />
<table style="height: 299px;" border="0" cellspacing="0" cellpadding="0" width="484">
<tbody>
<tr>
<td>
<p><div class="wp-caption aligncenter" style="width: 210px"><img title="Lactucina - molecola animata" src="http://mindunpacked.com/risorse/lactucin.gif" alt="Lactucina - molecola animata" width="200" height="200" /><p class="wp-caption-text">Lactucina - molecola animata</p></div></td>
<td>
<p><div id="attachment_285" class="wp-caption aligncenter" style="width: 165px"><a href="http://mindunpacked.com/wp-content/uploads/2008/12/virosa_serriola.jpg"><img class="size-medium wp-image-285" title="virosa_serriola" src="http://mindunpacked.com/wp-content/uploads/2008/12/virosa_serriola-200x300.jpg" alt="Illustrazione descrittiva" width="155" height="233" /></a><p class="wp-caption-text">Illustrazione descrittiva</p></div></td>
</tr>
</tbody>
</table>
<p></center></p>
<p style="margin-bottom: 0cm;" align="justify"><strong>ESTRAZIONE COMUNE</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">Sono necessarie almeno 2 piante (fiorite) per ottere una quantità apprezzabile di lactucarium. Per estrarre il liquido procuratevi una piccola ciotola in vetro. Cominciate a spezzare i rametti secondari, dove si trovano i fiori, e mettete il liquido che fuoriuscirà nella ciotola. Continuate a spezzare i rametti circa ogni centimetro, e accumulate il succo sempre nella ciotola. Fate lo stesso con il gambo. Le foglie contengono poco &#8220;latte&#8221;, quindi potete scartarle. Estratto tutto il lactucarium possibile dovete lasciarlo essiccare: ponete la ciotola in luogo asciutto e buio per almeno due giorni, fino ad ottenere una pasta di color marrone scuro.</p>
<p style="margin-bottom: 0cm;" align="left"><strong>ESTRAZIONE CHIMICA</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">Almeno 20g di materiale seccato e privato delle infiorescenze viene messo ammollo in una soluzione di alcol etilico a 95% e lasciato riposare per almeno 24 ore, mescolando ogni tanto. La lactucina è molto solubile nell&#8217;alcol, quindi finirà in soluzione con quest&#8217;ultimo. Passate le 24 ore un deposito marrone si sarà formato sul fondo, quindi il materiale erbaceo dovrà essere rimosso, e successivamente porre ad evaporare il liquido. Per agevolare questa fase è possibile riscaldarlo con un fornello, mantenendo il liquido ad una temperatura non superiore ai 50° C. Evaporato tutto l&#8217;alcol sul fondo rimarrà il lactucarium, che sarà possibile asportare con una lametta.<br />
Quello che si otterrà sarà lactucarium, e non la lactucina pura, in esso sono infatti presenti altre sostanze della pianta solubili in alcol, come ad esempio la clorofilla. Per filtrare tutti questi componenti estranei è possibile porre nuovamente il lactucarium ottenuto in alcol ad altissima percentuale (~100%) e porre il tutto nel frigorifero, in modo da mantenere la temperatura molto bassa. Far evaporare e ripetere il procedimento fino ad ottenere dei cristalli i più puri possibili.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/lactucina-e-lactucarium/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Il buffer overflow: introduzione</title>
		<link>http://mindunpacked.com/2008/il-buffer-overflow-introduzione/</link>
		<comments>http://mindunpacked.com/2008/il-buffer-overflow-introduzione/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 22:05:15 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Buffer overflow]]></category>
		<category><![CDATA[c/c++]]></category>
		<category><![CDATA[shellcode]]></category>
		<category><![CDATA[stack]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=267</guid>
		<description><![CDATA[Questo è il primo di tre articoli in cui cercherò di trattare una delle vulnerabilità più gravi che affliggono il software: il buffer overflow. In questo primo articolo spiegherò più o meno approfonditamente cos&#8217;è il buffer, lo stack, il bound checking eccetera, ed i principi base che permettono di sfruttare un buffer overflow a vantaggio [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm; text-align: justify;">Questo è il primo di tre articoli in cui cercherò di trattare una delle vulnerabilità più gravi che affliggono il software: il <strong>buffer overflow</strong>. In questo primo articolo spiegherò più o meno approfonditamente cos&#8217;è il buffer, lo stack, il bound checking eccetera, ed i principi base che permettono di sfruttare un buffer overflow a vantaggio di un eventuale attaccante.</p>
<p><span id="more-267"></span></p>
<p style="margin-bottom: 0cm;"><strong>Introduzione</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">Va anticipato che uno dei linguaggi di programmazione più predisposti al buffer overflow (d&#8217;ora in poi BOF) è senza dubbio il C/C++. Infatti a differenza di altri linguaggi permette al programmatore un controllo quasi completo sulla memoria &#8211; quasi quanto un linguaggio assembly – ma non sempre fa gli opportuni controlli, a scapito dei programmatori alle prime armi. Linguaggi come il Java, ad esempio, hanno una gestione molto sofisticata della memoria, ricorrendo ad algoritmi di de-allocazione e a sistemi come il <strong>Garbage Collector</strong>, quindi i rischi di BOF sono molto rari.<br />
Vediamo innanzi tutto cos&#8217;è il buffer. Nella sua accezione più generale un buffer è un&#8217;area di memoria contigua, con una dimensione prefissata, utilizzata per memorizzare dati omogenei. Nel linguaggio C un buffer è rappresentato dal puntatore all&#8217;indirizzo iniziale dell&#8217;area di memoria corrispondente. Alcune funzioni della libreria standard del C (strcpy(), strcat(), gets() e la famosa scanf()) operano su buffer di caratteri senza effettuare nessun controllo sulla dimensione del buffer di destinazione (bound checking): semplicemente arrestano la loro scrittura quando non hanno più caratteri disponibili. È evidente che in questi casi è abbastanza facile incorrere in un buffer overflow. Nel caso in cui il buffer mal gestito sia una variabile automatica, sia cioè allocato sullo stack, la situazione può venire sfruttata da un attaccante per sovrascrivere l&#8217;indirizzo di ritorno di una chiamata da funzione e forzare così l&#8217;esecuzione di codice malevolo, che può essere posizionato sia nel buffer stesso che in una variabile d&#8217;ambiente.<br />
In sintesi un buffer overflow avviene quando in un programma, al tempo di esecuzione, una certa istruzione tenta di scrivere dentro ad un buffer più informazioni di quante esso ne possa contenere.<br />
<!--adsense--></p>
<p style="margin-bottom: 0cm;"><strong>Organizzazione della memoria</strong></p>
<p style="margin-bottom: 0cm;">È possibile suddividere la memoria allocata ad un processo in tre zone, ognuna specializzata per una determinata funzione: un&#8217;area text, un&#8217;area dati statica ed un&#8217;area dati dinamica:</p>
<ul>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">L&#8217;area text è un&#8217;area di sola 	lettura, collocata nella parte più bassa dello spazio di 	indirizzamento di un processo, in cui vengono memorizzate le 	istruzioni del programma ed è condivisa da tutti i processi che 	eseguono lo stesso codice; un tentativo di scrittura in quest&#8217;area 	dà origine ad un errore.</p>
</li>
<li>
<p style="margin-bottom: 0cm;">L&#8217;area dati statica è a sua volta 	suddivisa in due regioni (data e bss), una per i dati inizializzati 	ed un&#8217;altra per i dati inizializzati; le variabili statiche trovano 	posto in quest&#8217;area.</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-align: justify;">L&#8217;area dati dinamica è divisa a 	sua volta in due parti: lo stack e  lo heap. Quest&#8217;ultima è un&#8217;area 	dati dinamica che viene allocata a run time attraverso le funzioni 	del C come malloc() e calloc(), e cresce verso gli indirizzi alti. 	Viene usato per gestire variabili dinamiche e puntatori. Andrò ora 	a descrivere un po&#8217; più nel dettaglio lo stack.</p>
</li>
</ul>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><strong>Lo stack e sua gestione</strong></p>
<p style="margin-bottom: 0cm; text-align: justify;">Lo stack è quell&#8217;area di memoria che si trova sul fondo della memoria e che viene utilizzata durante le chiamate alle funzioni per salvare lo stato corrente dell&#8217;esecuzione e per passare i parametri per argomento. Viene gestito con la politica LIFO (Last In, First Out) e mediante due istruzioni fondamentali del linguaggio assembly: PUSH e POP. La prima memorizza un dato, la seconda lo estrae seguendo il modello LIFO, l&#8217;ultimo ad entrare è il primo ad uscire. La memorizzazione dei dati nello stack segue un ordine inverso, cioè parte dal fondo e man mano che le informazioni vengono memorizzate, sale verso la cima della memoria.<br />
La gestione dello stack è affidata a due registri a 32-bit molto importanti, chiamati EBP e ESP (base pointer e stack pointer), usati – rispettivamente – per delimitare la cima e il fondo dello stack; quando si esegue una PUSH, il registro ESP viene decrementato di un numero di byte pari alla dimensione del dato memorizzato, quando si esegue una POP il registro ESP viene invece incrementato. Le variazioni di ESP e EBP possono inoltre essere fatte anche direttamente, tramite operazioni di somma e sottrazione (ADD e SUB): ad esempio l&#8217;istruzione SUB ESP,5 riserva cinque byte nello stack. Questo tipo di struttura si rivela efficiente e utile nella gestione della gestione delle chiamate di funzioni e procedure in un programma, costituendo quello che è il meccanismo della “call chain”: una funzione può infatti richiamare un&#8217;altra funzione che a sua volta può chiamarne un&#8217;altra ancora e così via. Il sistema operativo deve poter tener traccia di tutte le chiamate innestate fra loro ed essere in grado di tornare a punti prestabiliti del programma dove richiesto. Ogni chiamata ad una funzione viene tradotta in una istruzione di tipo CALL, che ha l&#8217;effetto di congelare l&#8217;esecuzione del codice fino a quel punto, passando poi il controllo alla funzione chiamata, dopo aver salvato lo stato corrente e l&#8217;indirizzo di ritorno (return address), che servirà per riportare l&#8217;esecuzione nel punto in cui si era interrotta (il registro EIP è quello che punta sempre all&#8217;istruzione corrente). Da questo meccanismo si evince una prima considerazione importante: poiché l&#8217;indirizzo di ritorno viene salvato nello stack, una eventuale corruzione di tale area dati impedirà ad un qualsiasi programma di ritornare in uno stato consistente, con conseguente crash dell&#8217;esecuzione.<br />
Per approfondimenti riguardo allo stack si veda il seguente link: <a href="http://blacklight.gotdns.org/wiki/index.php/Stack">Stack on Hacknowledge</a></p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm; text-decoration: none;"><strong>Usi malevoli del buffer overflow</strong></p>
<p style="margin-bottom: 0cm; text-decoration: none; text-align: justify;">Come ho detto ad inizio articolo abbiamo a che fare con un errore particolarmente grave, che permetterebbe ad un hacker di ottenere una shell (anche root in certi casi) sulla macchina vittima.<br />
Detto sinteticamente – comunque nei prossimi articoli vedremo il tutto più nel dettaglio – è possibile far eseguire del codice macchina semplicemente sovrascrivendo l&#8217;indirizzo di ritorno e facendolo puntare ad uno shellcode. Quest&#8217;ultimo è un “programma” in grado di sfruttare un buffer overflow, e solitamente provoca l&#8217;apertura di una shell &#8211; per questo shellcode &#8211; sulla macchina vittima. Uno shellcode viene solitamente scritto tramite codici esadecimali che identificano le varie istruzioni assembly da eseguire, successivamente questo codice viene iniettato nel buffer e fatto eseguire modificando l&#8217;indirizzo di ritorno della funzione vulnerabile. I rischi di un errore del genere in alcuni casi possono essere gravissimi, ad esempio un login che va in buffer overflow se il nome utente è troppo lungo&#8230;<br />
Ecco un&#8217;immagine che forse vi faciliterà la comprensione di quanto detto:</p>
<p style="margin-bottom: 0cm; text-decoration: none;">
<p style="text-align: center;"><img class="size-full wp-image-268 aligncenter" title="stack" src="http://mindunpacked.com/wp-content/uploads/2008/12/stack.gif" alt="" width="460" height="279" /></p>
<p style="margin-bottom: 0cm; text-decoration: none; text-align: justify;">In ogni caso questo è un overflow dello stack – uno dei più comuni – ma ne esistono anche altri meno conosciuti, ed anche più difficili da sfruttare: heap overflow, frame pointer exception e l&#8217;adjacent memory overflow.<br />
L&#8217;overflow dello stack rimane il più facile da sfruttare, poiché permette di maneggiare in maniera efficace i registri EBP, ESP e EIP, fondamentali per poter eseguire del codice</p>
<p style="margin-bottom: 0cm; text-decoration: none;">Ma vediamo ora com&#8217;è possibile prevenire un BOF:</p>
<ul>
<li>
<p style="margin-bottom: 0cm; text-decoration: none;"><strong>Non 	Executable Stack</strong>: questa è la soluzione più radicale. Modificando 	il kernel del sistema si può rendere il segmento che contiene i 	dati dello stack non-eseguibile, in modo che se accidentalmente o 	volutamente un programma dovesse finire in quellaa zona di memoria 	verrebbe generato un cosiddetto protection fault, terminando il 	processo.</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-decoration: none;"><strong>Random 	Stack Address</strong>: Per poter pilotare il flusso di esecuzione, un 	exploit deve disporre di indirizzi affidabili e validi da assegnare 	ai registri EIP e ESP. Utilizzando uno stack con modalità di 	indirizzamento casuale, si potrebbe complicare la vita ad un 	eventuale attaccante nella realizzazione di exploit a compatibilità 	universale, che cioè funzionino in qualsiasi sistema in cui sia 	presente il programma vulnerabile.</p>
</li>
<li>
<p style="margin-bottom: 0cm; text-decoration: none;"><strong>Bound 	Checking</strong>: Il problema degli overflow nasce principalmente da 	disattenzioni da parte del programmatore e del compilatore, che non 	controlla in anticipo se una variabile è soggetta a “traboccare”. 	Comunque anche nel C/C++ sono presenti alcuni accorgimenti da 	rispettare, e perfino delle funzioni safe, che appunto effettuano 	dei controlli sull&#8217;input in modo che non superi la grandezza del 	buffer a cui è destinato. Di seguito degli esempi:</p>
</li>
</ul>
<pre class="brush: cpp;">
strcpy(buf, ptr); //insicuro
strncpy(buf, sizebuf(buf), ptr); //sicuro
</pre>
<p>oppure con il classico scanf():</p>
<pre class="brush: cpp;">

char buf[10];
scanf(&quot;%s&quot;, buf); //insicuro
scanf(&quot;%10s&quot;, buf); //sicuro
</pre>
<p style="margin-bottom: 0cm; text-decoration: none; text-align: justify;">Nei prossimi due articoli tratterò appunto questo tipo di buffer overflow, applicandolo ai due sistemi operativi più famosi, ovvero Windows e Linux.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/il-buffer-overflow-introduzione/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Reti neurali attraverso algoritmi genetici in C++. Parte V</title>
		<link>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-v/</link>
		<comments>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-v/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 13:07:07 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Algoritmi genetici]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Intelligenza artificiale]]></category>
		<category><![CDATA[Reti neurali]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=252</guid>
		<description><![CDATA[In questa penultima parte della serie di articoli dedicati alle reti neurali, vedremo come creare una classe che riunisca tutto cio&#8217; che abbiamo programmato in precedenza e ne renda piu&#8217; facile l&#8217;utilizzo. Era gia&#8217; possibile utilizzare le classi cosi&#8217; com&#8217;erano, ma in questo modo ci rendiamo la vita piu&#8217; semplice. Inoltre c&#8217;e&#8217; da notare che [...]]]></description>
			<content:encoded><![CDATA[<p>In questa penultima parte della serie di articoli dedicati alle reti neurali, vedremo come creare una classe che riunisca tutto cio&#8217; che abbiamo programmato in precedenza e ne renda piu&#8217; facile l&#8217;utilizzo. Era gia&#8217; possibile utilizzare le classi cosi&#8217; com&#8217;erano, ma in questo modo ci rendiamo la vita piu&#8217; semplice. Inoltre c&#8217;e&#8217; da notare che quello che faremo oramai non ho molto a che fare con l&#8217;implementazione della rete, ma e&#8217; piu&#8217; una questione di ordine e OOP.</p>
<p><span id="more-252"></span></p>
<p align="center"><strong>Riunire il tutto.</strong></p>
<p align="justify">In questo piccolo paragrafo vedremo come fare comunicare tra loro le due classi attraverso una terza ed ultima classe che si occupa della gestione di tutte le operazioni. In realtà questa classe è superflua perchè è già possibile, con le sole classi Population e NeuralNet, creare una rete neurale funzionante ma essa ci rende molto più comoda la scritture del codice. Essa contiene per lo più funzioni ausiliarie come quella per caricare il training set (senza dover parsare manualmente il file), o per salvare e caricare i pesi della rete neurale e per questo non mi soffermerò molto sul codice. La funzione più importante è quella che esegue l&#8217;allenamento della rete neurale, ma vediamo prima il codice della classe:</p>
<pre class="brush: cpp;">
class NNController {
	public:
		NNController(int c_numInputNeurons, int c_numOutputNeurons,
		int c_numHiddenLayers, int c_numNeuronsPerLayer);
		void loadTrainingSet(string inputFile, string outputFile);
		void train();
		void saveWeights(string file);
		void loadWeights(string file);
		void test();
	private:
		vector&lt; vector &gt; inputData; // Training set
		vector&lt; vector &gt; outputData;
		NeuralNet* N;
		Population* P;
		Chromosome* C;
};
</pre>
<p align="justify">Il costruttore ha gli stessi parametri di quello della classe NeuralNet che servono ad inizializzare l&#8217;oggetto N all&#8217;interno di questa classe.</p>
<p align="justify">La funzione loadTrainingSet(string inputFile string outputFile) carica appunto il training set: essa riceve come argomenti i nomi di due file, il primo deve contenere gli input da passare alla rete neurale mentre il secondo gli output desiderati corrispondenti agli input. Per esempio, se stiamo addestrando la rete a fare la somma di due numeri, ed il file contenente l&#8217;input contenesse:</p>
<p align="justify">
<p align="justify">0 1</p>
<p align="justify">0 2</p>
<p align="justify">
<p align="justify">Quello contenente l&#8217;output dovrebbe contenere:</p>
<p align="justify">1</p>
<p align="justify">2</p>
<p align="justify">(Gli input devono essere separati tra di loro da uno spazio ed ogni riga deve contenere ovviamente sempre lo stesso numero di input che deve essere a sua volta uguale al numero dei neuroni di input specificato nel codice).</p>
<p align="justify">Le funzioni saveWeights(string file) e loadWeights(string file) servono rispettivamente a salvare i pesi della rete neurale (generalmente dopo che questa è allenata) e a poterli caricare in seguito senza dover ripetere l&#8217;addestramento.</p>
<p align="justify">La funzione test() serve invece a poter testare la rete con vari input dopo che questa è stata allenata. Ho conservato volutamente alla fine la funzione train() perchè è l&#8217;unica un po più complessa e serve ad effettuare l&#8217;allenamento della rete.</p>
<pre class="brush: cpp;">
void NNController::train() {
	double currentErr = 0; int i = 0; double bestFit = 99999999;&lt;
	while (bestFit &gt; MAX_ERROR) {
		if (i &gt;= MAX_EPOCHS) {
			break;
		}
		for (int j = 0; j &lt; POPULATION_SIZE; j++) {
			currentErr = 0;
			for (int k = 0; k &lt; inputData.size(); k++) {
				N-&gt;run(inputData[k], (*P)[j]);
				currentErr += N-&gt;globalError(outputData[k]) / inputData.size()
			}
			(*P)[j]-&gt;setFitness(currentErr);
		}
		bestFit = P-&gt;best()-&gt;getFitness();
		if (i % UPDATE == 0) {
			cout &lt;&lt; &quot;(&quot; &lt;&lt; i &lt;&lt; &quot;) - &quot;&lt;&lt; &quot;Best = &quot; &lt;&lt; bestFit
			     &lt;&lt; &quot;\t&quot; &lt;&lt; &quot;Worst = &quot; &lt;&lt; P-&gt;worst()-&gt;getFitness()
			     &lt;&lt; endl;
		}
		P-&gt;next();
		i++;
	}
}
</pre>
<p><!--adsense--></p>
<p align="justify">La funzione esegue un ciclo while che termina o quando il fitness raggiunge un livello accettabile (cioè l&#8217;errore raggiunto è minore o uguale all&#8217;errore massimo stabilito in precedenza e definito nella costante MAX_ERROR) oppure quando (vedete il break) il numero di epoche (cioè di cicli di riproduzione della popolazione) supera un certo limite. Dentro questo ciclo while c&#8217;è un ulteriore ciclo for che scorre tutti gli elementi della popolazione (che, come oramai dovrebbe essere chiaro, rappresenta una configurazione dei pesi della rete neurale) e per ognuno esegue tutto il training set in input. Il fitness di questo individuo sarà l&#8217;errore medio che il cromosoma ha sugli elementi del training set. Un errore pari a 0, che corrisponde alla perfezione assoluta, è praticamente impossibile da raggiungere e quindi, a seconda dei casi, ci si può accontentare di un errore più o meno alto come, per esempio, 0.001.</p>
<p align="justify">La funzione stampa anche un output ogni tanto per informare l&#8217;utente a che punto è arrivato l&#8217;allenamento, e dipende dal valore della costante UPDATE: se per esempio questa vale 50, ogni 50 generazioni sarà stampato un messaggio contente i fitness del migliore e del peggiore cromosoma della popolazione corrente.</p>
<p align="justify">Quando questa funzione termina la nostra rete neurale è allenata (con un errore massimo stabilito dalla costante MAX_ERROR) ed è possibile testarla tramite il metodo test() fornito dalla stessa classe.</p>
<p align="justify">Vediamo ora un codice di esempio di rete neurale realizzata con le nostre classi:</p>
<pre class="brush: cpp;">
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;sstream&gt;
#include &lt;vector&gt;
#include &lt;ctime&gt;
#include &lt;cmath&gt;

using namespace std;

/* Misc.hpp è un header che contiene le varie costanti come
MAX_POPULATION, ELITISM, MAX_TOUR, etc...
Gli altri header contengono le varie classi */
#include &quot;Misc.hpp&quot;
#include &quot;GenAlg.hpp&quot;
#include &quot;NeuralNet.hpp&quot;
#include &quot;NNController.hpp&quot;

int main() {
	/* Alla riga seguente creiamo una rete neurale con 2 neuroni
	di input, 1 neurone di output e 0 layer nascosti */
	NNController NC(2, 1, 0, 0);
	/* Carica il training set contenuto nei due file */
	NC.loadTrainingSet(&quot;input&quot;, &quot;output&quot;);
	NC.train();
	cout &lt;&lt; &quot;*** La rete e' allenata ***&quot; &lt;&lt; endl;
	NC.test();
}
</pre>
<p align="justify">Come vedete il codice è davvero basilare eppure una rete neurale come quella di questo esempio, sarebbe in grado di imparare a fare la somma di due numeri con soli tre neuroni!</p>
<p align="center"><strong>Come impostare una rete neurale.</strong></p>
<p align="justify">Abbiamo visto la creazione pratica di una rete neurale ma come avete notato il risultato ottenuto da una rete dipende da una miriade di fattori come per esempio il numero di livelli, il numero di neuroni presente nei livelli nascosti, la funzione di trasferimento, etc&#8230; di conseguenza vi starete probabilmente chiedendo quali sono le impostazioni migliori per una rete neurale. Chiaramente non esistono delle impostazioni migliori in assoluto, ma dipende tutto dal problema che dobbiamo analizzare, di conseguenza quelle che scriverò qui saranno solo delle brevi linee guida da tenere in considerazione ma non delle regole fisse.</p>
<p align="justify">Ho gia parlato in precedenza delle funzioni di attivazione e di quali sia più comodo usare a seconda dei casi, ora parleremo del numero dei livelli.</p>
<p align="justify">Quanti livelli nascosti vanno usati? Nell&#8217;esempio precedente abbiamo creato una rete capace di imparare a fare la somma dei due numeri senza utilizzare nessun livello nascosto e in molti casi può verificarsi questa eventualità. Generalmente, nei casi restanti, un solo livello nascosto è più che sufficiente per ottenere risultati corretti. Dal punto di vista matematico possiamo dire che una rete neurale con i soli livelli si input e outputè capace di risolvere problemi linearmente separabili, mentre per problemi non linearmente separabili sono richiesti uno o più livelli nascosti.</p>
<p align="justify">Il numero di neuroni per ogni livello nascosto può essere un&#8217;altra incognita nella creazione della rete neurale: esso dipende da più fattori come il numero dei neuroni di input e di output, la dimensione del training set, la funzione di attivazione, l&#8217;algoritmo di apprendimento, etc&#8230; Esistono diverse regole approssimative che cercano di fornire un modo per calcolare il numero di unità nascoste necessarie (per esempio: &#8220;il numero di unità nascoste deve essere sempre minore del doppio dei neuroni di input&#8221;) ma molto spesso esse sono inutili. La cosa migliore è fare alcune prove e trovare il numero di unità che fornisce un errore minimo.</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-v/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>La ricina</title>
		<link>http://mindunpacked.com/2008/la-ricina/</link>
		<comments>http://mindunpacked.com/2008/la-ricina/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 13:47:01 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Chimica]]></category>
		<category><![CDATA[depurinazione]]></category>
		<category><![CDATA[protenia]]></category>
		<category><![CDATA[ricina]]></category>
		<category><![CDATA[ricino]]></category>
		<category><![CDATA[tossina]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=234</guid>
		<description><![CDATA[
La ricina è una proteina che viene comunemente estratta dai semi di ricino (Ricinus communis), li stessi che vengono usati per produrre il rispettivo olio. Questa proteina viene solitamente scartata durante la lavorazione dei semi, ed in alcuni casi usata come medicinale. A contatto con il corpo umano si comporta come una tossina, in grado [...]]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p style="margin-bottom: 0cm; text-align: justify;">La <strong>ricina</strong> è una proteina che viene comunemente estratta dai semi di ricino (<em>Ricinus communis</em>), li stessi che vengono usati per produrre il rispettivo olio. Questa proteina viene solitamente scartata durante la lavorazione dei semi, ed in alcuni casi usata come medicinale. <span id="more-234"></span>A contatto con il corpo umano si comporta come una tossina, in grado di inibire la sintesi delle proteine da parte dell&#8217;organismo. La dose letale è decisamente piccola, nell&#8217;ordine dei 500 microgrammi, e non sono conosciuti antidoti, ma solo un vaccino che potrebbe prevenire gli effetti della sostanza. Proprio per questo motivo la ricina viene usata spesso come arma chimica per attentati et simila: per uccidere un uomo di taglia media è sufficiente graffiarlo con qualche oggetto “sporco” di cristalli di ricina. E&#8217; una sostanza estremamente pericolosa, dal momento che può venire assorbita dalla pelle, anche priva di lacerazioni. Inoltre gli effetti si manifestano molto in fretta se viene ingerita o inalata.</p>
<p style="margin-bottom: 0cm; text-align: justify;">
<table style="height: 220px;" border="0" cellspacing="0" cellpadding="0" width="628">
<tbody>
<tr>
<td style="text-align: center; padding-left: 30px;"><img class="aligncenter" title="Ricina" src="http://mindunpacked.com/risorse/ricina.gif" alt="" width="200" height="200" /></td>
<td>
<p style="margin-bottom: 0cm; text-align: justify; padding-left: 60px;">La ricina è una protenia inattivante del ribosoma di tipo 2 (RIP II), si può dividere in due catene molecolari: RTA e RTB (Ricin Toxin A/B), ed è in grado di infiltrarsi all&#8217;interno di una cellula (citosol). Dal momento che questa sostanza resiste a molti tipi di pH, il libosoma cellulare (lo stomaco della cellula, detto in parole povere) può fare ben poco per difendere la stessa. Una singola catena molecolare come l&#8217;RTA, una volta infiltratasi nella cellula, può <a href="http://it.wikipedia.org/wiki/Depurinazione">depurinare</a> circa 1500 ribosomi al minuto. Le conseguenze sono gravissime già dopo poche ore.</p>
</td>
</tr>
</tbody>
</table>
<p><strong>ESTRAZIONE</strong></p>
<p style="text-align: justify;">I semi della pianta vanno triturati abbastanza finemente per poi essere immersi in una soluzione acida. Questa può essere prodotta aggiungendo dell&#8217;acido cloridrico a dell&#8217;acqua distillata fino a raggiungere un pH ~4. Il tutto andrà mescolato energicamente e lasciato riposare per almeno 24 ore. A questo puntotutti i depositi non solubili vanno filtrati con un filtro a trama fine,  ad ottenere una soluzione priva di parti insolubili.<br />
Ora la ricina è disciolta nella soluzione acida, quindi per farla precipitare va aggiunto del solfato di sodio arrivando ad un pH ~8. il tutto andrà di nuovo filtrato, questa volta conservando il deposito (ricina) e scartando la soluzione acquosa. Sarà meglio effettuare un lavaggio della ricina con una soluzione di solfato di sodio al 20% con acqua distillata, questo rimuoverà eventuali sostanze indesiderate.<br />
Ripetere tutto una seconda volta per ottenere un prodotto più puro.</p>
<p style="text-align: justify;"><strong>Come ho già detto questa sostanza è molto pericolosa, e può facilmente entrare in contatto con l&#8217;organismo senza le dovute precauzioni. La sua estrazione (anche se solo a fini di studio) è sconsigliata.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/la-ricina/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reti neurali attraverso algoritmi genetici in C++. Parte IV</title>
		<link>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-iv/</link>
		<comments>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-iv/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 12:04:57 +0000</pubDate>
		<dc:creator>Francesco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Algoritmi genetici]]></category>
		<category><![CDATA[Intelligenza artificiale]]></category>
		<category><![CDATA[Reti neurali]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=200</guid>
		<description><![CDATA[Le classi Chromosome e Population.
Abbiamo finito l&#8217;implementazione della rete ed ora possiamo passare alla parte relativa all&#8217;addestramento della stessa, che come ho già detto, verrà realizzata tramite algoritmi genetici. Vediamo la classe Chromosome:


class Chromosome {
	public:
		Chromosome(int c_w);
		Chromosome(vector&#60;double&#62; weights); // overload
		void setWeight(int i, double val);
		double getWeight(int i) const;
		void setFitness(double fit);
		double getFitness() const;
		int getWeightsNum() const;
		void mutate();
	private:
		vector&#60;double&#62; DNA;
		double fitness;
};

Innanzitutto [...]]]></description>
			<content:encoded><![CDATA[<p align="center"><strong>Le classi Chromosome e Population.</strong></p>
<p align="justify">Abbiamo finito l&#8217;implementazione della rete ed ora possiamo passare alla parte relativa all&#8217;addestramento della stessa, che come ho già detto, verrà realizzata tramite algoritmi genetici. Vediamo la classe Chromosome:</p>
<p align="justify"><span id="more-200"></span></p>
<pre class="brush: cpp;">
class Chromosome {
	public:
		Chromosome(int c_w);
		Chromosome(vector&lt;double&gt; weights); // overload
		void setWeight(int i, double val);
		double getWeight(int i) const;
		void setFitness(double fit);
		double getFitness() const;
		int getWeightsNum() const;
		void mutate();
	private:
		vector&lt;double&gt; DNA;
		double fitness;
};
</pre>
<p align="justify">Innanzitutto essa possiede due costruttori. Il primo serve nel caso volessimo inizializzare un cromosoma con pesi random specificando solamente il numero dei pesi  (in pratica la lunghezza del DNA); il secondo serve quando vogliamo creare un cromosoma con dei pesi ben precisi passandogeli come argomento: quest&#8217;ultimo viene usato per implementare una funzione che permette di salvare i pesi dopo che la rete neurale è allenata e di poterli caricare per evitare di dover ripetere ogni volta l&#8217;allenamento.</p>
<p align="justify">Come potete vedere le funzioni getWieght(int) e setWeight(int, double) hanno dei compiti abbastanza evidenti così come setFitness(double) e getFitness().</p>
<p align="justify">La funzione mutate() applica il famoso operatore genetico delle mutazione al cromosoma, vediamone il codice:</p>
<pre class="brush: cpp;">
void Chromosome::mutate() {
	if (dRand() &lt;= MUTATION_RATE) {
		DNA[rand()%DNA.size()] += wRand()*MAX_PERTURBATION;
	}
}</pre>
<p align="justify">Viene generato un numero random compreso tra 0 e 1 e se è minore del valore di MUTATION_RATE la mutazione viene effettuata. Nella parte sugli algoritmi genetici avevamo visto che, quando il DNA è codificato in forma binaria la mutazione agisce semplicemente trasformando uno 0 in un 1 o viceversa. Nel nostro caso, invece, la mutazione non fa altro che aggiungere o sottrarre un piccolo valore compreso tra 0 e MAX_PERTURBATION ad un peso qualsiasi del DNA (wRand() genera infatti un numero compreso tra -1 e 1 quindi il valore di MAX_PERTURBATION può essere sottratto o aggiunto, a seconda del numero generato da wRand()).</p>
<p align="justify">La classe Population ingloba un array di oggetti Chromosome* cioè la popolazione vera e propria, più una serie di metodi come la riproduzione, il crossover, etc&#8230; ecco il codice:</p>
<pre class="brush: cpp;">
class Population {
	public:
		Population(int c_num, int c_numw);
		void crossover(Chromosome* a1, Chromosome* a2, Chromosome* b1, Chromosome* b2);
		Chromosome* getChromosomeFromTournament();
		void next();

		Chromosome* best();
		Chromosome* worst();
		Chromosome* operator[](int i);
	private:
		int length;
		vector&lt;Chromosome*&gt; popv;
};</pre>
<p><!--adsense--><br />
Il costruttore è abbastanza semplice: prende come argomenti il numero di individui di cui è formata la popolazione, ed il numero di pesi per ogni individui cioè la lunghezza del DNA (che chiaramente è uguale per tutti gli individui).</p>
<p align="justify">Il metodo del crossover incrocia il DNA dei primi due cromosomi che gli passiamo come argomento e lo mette negli ultimi due, sempre se il numero random generato sia minore della costante CROSSOVER_RATE: un valore di quest&#8217;ultima costante pari a 0.7, per esempio, vuol dire che nel 70% dei casi il crossover viene effettuato. Se ciò non avviene gli individui si riproducono così come sono.</p>
<pre class="brush: cpp;">
void Population::crossover(Chromosome* a1, Chromosome* a2, Chromosome* b1, Chromosome* b2) {
	if (dRand() &lt;= CROSSOVER_RATE) {
		int crosspoint = rand()%length;

		for (int i = 0; i &lt; crosspoint; i++) {
			b1-&gt;setWeight(i, a1-&gt;getWeight(i));
			b2-&gt;setWeight(i, a2-&gt;getWeight(i));

			b1-&gt;setWeight(length-(i+1),
			a1-&gt;getWeight(length-(i+1)));
			b2-&gt;setWeight(length-(i+1),
			a2-&gt;getWeight(length-(i+1)));
		}
	} else { // Se non fa il crossover riproduce gli stessi cromosomi.
		b1 = a1;
		b2 = a2;
	}
}</pre>
<p>La funzione getChromosomeFromTournament() svolge il cosiddetto &#8220;torneo&#8221; fra i cromosomi e seleziona quello con il miglior fitness. Essa non è altro che il nostro metodo di selezione:</p>
<pre class="brush: cpp;">
Chromosome* Population::getChromosomeFromTournament() {
	vector&lt;Chromosome*&gt; r;
	for (int i = 0; i &lt; NUM_TOUR; i++) {
		r.push_back(popv[rand()%popv.size()]);
	}
	sort(r.begin(), r.end(), compareChromosomes);
	return r[0];
}
</pre>
<p><!--adsense--></p>
<p align="justify">Per svolgere il &#8220;torneo&#8221; viene creato un vettore che conterrà i cromosomi scelti casualmente dalla popolazione: NUM_TOUR è un&#8217;altra costante che definisce quanti cromosomi saranno scelti. Più NUM_TOUR è alta più basse saranno le probabilità degli individui più deboli di sopravvivere e ricordate che questo può non essere sempre un vantaggio; nel caso estremo in cui NUM_TOUR sia uguale alla grandezza della popolazione verrebbe sempre e solo scelto il cromosoma migliore della prima generazione (che poi tanto buono non è visto che nella prima generazione il DNA è random) portando così a tutt&#8217;altro che la soluzione del problema.</p>
<p align="justify">L&#8217;array così ottenuto viene ordinato in base al fitness (la funzione compareChromosomes() non fa altro che restituire il cromosoma che ha il fitness minore tra i due che riceve come argomento) e così l&#8217;elemento 0 dell&#8217;array conterrà quello con il fitness più basso (ricordate che per noi fitness più basso equivale ad errore più basso e quindi a punteggio migliore) mentre l&#8217;ultimo quello con fitness più alto. Questa funzione, insieme a quella del crossover, viene utilizzata nel metodo next() che effettua la riproduzione dell&#8217;intera popolazione finchè non si ha una nuova popolazione con lo stesso numero di individui della precedente.</p>
<pre class="brush: cpp;">
void Population::next() {
	vector&lt;Chromosome*&gt; newPop;

	sort(popv.begin(), popv.end(), compareChromosomes);

	Chromosome* b1 = new Chromosome(length);
	Chromosome* b2 = new Chromosome(length);

	// Garantisce la sopravvivenza dell'inviduo con il fitness piu' alto
	// della popolazione precedente.
	for (int i = 0; i &lt; ELITISM; i++) {
		newPop.push_back(popv[0]);
	}
	while (newPop.size() &lt; popv.size()) {
		Chromosome* a1 = getChromosomeFromTournament();
		Chromosome* a2 = getChromosomeFromTournament();

		crossover(a1, a2, b1, b2);
		b1-&gt;mutate();
		b2-&gt;mutate();
		newPop.push_back(b1); newPop.push_back(b2);
	}

	popv = newPop;
}</pre>
<p align="justify">Viene creato inizialmente un nuovo vettore che conterrà i nuovi individui ed il vettore contenente la popolazione viene ordinato in ordine di fitness (come abbiamo fatto nel metodo per svolgere il &#8220;torneo&#8221;): questo serve per mettere in atto un procedimento particolare definito elitismo. L&#8217;elisitmo consiste nel fare sopravvivere sempre, nella generazione successiva, una o più copie dell&#8217;elemento che nella generazione precedente aveva totalizzato il punteggio migliore: questo ci garantisce che, quali che siano le ricombinazioni che vengono effettuate sui nuovi individui, non perderemo mai il risultato raggiunto, e inoltre,  queste copie possono fornire un aiuto decisivo al raggiungimento della soluzione. ELITISM è una costante che definisce quante copie del miglior cromosma vadano inserite nella nuova popolazione. Nel ciclo while vengono selezionati due cromosomi dal &#8220;torneo&#8221;, viene fatto su di loro il crossover e sui nuovi individui generati viene effettuata una mutazione (sempre con la percentuale che abbiamo stabilito nella costante MUTATION_RATE) e poi vengono inseriti nel nuovo vettore. Quando questo vettore raggiunge le dimensioni della vecchia popolazione, si esce dal ciclo ed esso viene copiato sulla popolazione originale.</p>
<p align="justify">Le altre funzioni della classe sono abbastanza ovvie: best() serve a selezionare il cromosoma con il fitness migliore, worst() il peggiore e l&#8217;overloading dell&#8217;operatore [] ci permette di accedere ai membri della popolazione come se fossero elementi di un array senza dover scrivere un apposita funzione del tipo getChromosome(int i) (come quella che abbiamo usato per i neuroni: volendo anche lì si può fare infatti l&#8217;overloading dell&#8217;operatore []).</p>
<p align="justify">Manca solo una classe per riunire tutto il codice che abbiamo fatto fino ad ora e la nostra rete sarà utilizzabile (anche se, in pratica, e&#8217; utilizzabile anche da adesso con qualche sforzo in più): la vedremo nella prossima parte, intanto vi do i link a tutte le parti precedenti:</p>
<ol>
<li><a title="Reti neurali e algoritmi genetici parte I" href="http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-i/" target="_self">Reti neurali e algoritmi genetici I</a></li>
<li><a title="Reti neurali e algoritmi genetici parte II" href="http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-ii/" target="_self">Reti neurali e algoritmi genetici II</a></li>
<li><a title="Reti neurali e algoritmi genetici parte III" href="http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-iii/" target="_self">Reti neurali e algoritmi genetici III</a></li>
</ol>
<p>Alla prossima&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2008/reti-neurali-attraverso-algoritmi-genetici-in-c-parte-iv/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- www.000webhost.com Analytics Code -->
<script type="text/javascript" src="http://analytics.hosting24.com/count.php"></script>
<noscript><a href="http://www.hosting24.com/"><img src="http://analytics.hosting24.com/count.php" alt="web hosting" /></a></noscript>
<!-- End Of Analytics Code -->
