bene, abbiamo visto un breve sunto di cio' che si puo' fare
con questo compilatore..
vediamo di creare qualcosa di concreto, un piccolo oggettino..
prendiamo questo listato c che ottiene una stringa criptata secondo una variante dell'algoritmo di Vigenere..
codice:
#include<stdio.h>
#include<string.h>
int main (int argc,char ** argv)
{ //magic key la chiave di Vigenere che ci serve
char *m_key = " KentaroMiura1234567890ABCDEFGHIJKLMNOPQRSTUVZ";
//se non viene passato un parametro esce con un errore
if (argc <2){
printf("inserire una stringa come parametro");
return -1;
}
[COLOR] // setta un indice di partenza all' interno della stringa[/COLOR]
int par=strlen(argv[1]) % strlen(m_key);
unsigned int i;
[COLOR] //stampa la stringa criptata(le tre cifre sono il codice Ascii ottenuto)[/COLOR]
for(i=0;i<strlen(argv[1]);i++)
printf("%03d",(unsigned char)argv[1][i]^m_key[(i+par)%strlen(m_key)]);
return 0;
}
notiamo che la conversione in d e' abbastanza semplice, cambia veramente poco
infatti, ho scelto volutamente questo esempio per favi notare che tutti gli
operatori del c sono supportati compresi Xor bit a bit(^) che mod il resto della divisione (%) ..
codice:
int main (char[][] args)
{
char[] m_key = " KentaroMiura1234567890ABCDEFGHIJKLMNOPQRSTUVZ";
if (args.length <2){
printf("inserire una stringa come parametro");
return -1;
}
int par=args[1].length % m_key.length;
for(uint i=0;i<args[1].length;i++)
printf("%03d",cast(ubyte) args[1][i]^m_key[(i+par)%m_key.length]));
return 0;
}
praticamente le differenze sono minime..
in particolare anziche' utilizzare la funzione strlen si usa l' attributo length delle stringhe, e unsigned char diventa ubyte
(per vedere la tabella di conversione c --> d si controlli il file c:\dmd\html\d\ctod.html)
ora per riottenere la stringa originale il listato c sara' piu o meno cosi' :
codice:
#include<stdio.h>
#include<string.h>
int main (int argc,char ** argv)
{
//la solita chiave
char *m_key = " KentaroMiura1234567890ABCDEFGHIJKLMNOPQRSTUVZ";
//controlla se c'e' il parametro
if (argc <2){
printf("inserire una stringa come parametro");
return -1;
}
//ricava la partenza
int par=(strlen(argv[1])/3) % strlen(m_key);
unsigned int i;
//riconverte la stringa
for(i=0;i<strlen(argv[1])/3;i++)
printf("%c",(unsigned char)((argv[1][i*3]-'0')*100+(argv[1][i*3+1]-'0')*10+(argv[1][i*3+2]-'0'))^m_key[(i+par)%strlen(m_key)]);
return 0;
}
che convertito in d sara' :
codice:
int main (char[][] args)
{
char[] m_key = " KentaroMiura1234567890ABCDEFGHIJKLMNOPQRSTUVZ";
if (args.length <2){
printf("inserire una stringa come parametro");
return -1;
}
int par=args[1].length /3% m_key.length;
for(uint i=0;i<args[1].length/3;i++)
printf("%c",(args[1][i*3]-'0')*100+(args[1][i*3+1]-'0')*10+args[1][i*3+2]-'0'^m_key[(i+par)%m_key.length]);
return 0;
}
ora sarebbe interessante costruire un oggetto che contenga questi 2 metodi anziche' un programmino stand-alone..
magari espandendolo in maniera tale da passargli una chiave qualsiasi..
codice:
import std.c.stdio;
import std.string;
static class vigenere {
//la nostra chiave di criptaggio
private char[] m_key;
//ecco il costruttore base
this(){
m_key=" KentaroMiura1234567890ABCDEFGHIJKLMNOPQRSTUVZ";
}
//costruttore per cambiare la chiave
this(char[] key){
m_key=key;
}
//metodo decripta praticamente uguale all' esempio precedente
public char[] decripta(char[] str){
int par=str.length /3% m_key.length;
char[] strOut="";
for(uint i=0;i<str.length/3;i++)
strOut~=(str[i*3]-'0')*100+(str[i*3+1]-'0')*10+str[i*3+2]-'0'^m_key[(i+par)%m_key.length];
return strOut;
}
//metodo cripta leggermente cambiato per salvare su una stringa anziche' stampare a video
public char[] cripta(char[] str){
int par=str.length % m_key.length;
char[] strOut="";
for(uint i=0;i<str.length;i++){
char[4] tmp;
sprintf(tmp,"%03d",cast(ubyte) str[i]^m_key[(i+par)%m_key.length]);
strOut~=std.string.toString(tmp);
}
return strOut;
}
}
per provarlo usiamo questo sorgente..
(basta appenderlo alla fine del listato e vuala'!)
codice:
int main (char[][] args){
//primo oggetto che invoca il costruttore di base ovvero con la chiave ' KentaroMiura1234567890ABCDEFGHIJKLMNOPQRSTUVZ'
vigenere v = new vigenere();
//costruttore aggiunto la chiave di criptaggio sara' 'abcabcabc'
vigenere w = new vigenere("abcabcabc");
printf("primo oggetto\n");
printf("chiave usata:\n%.*s\n",v.m_key~"\0");
printf("cripta e decripta ciao\n%.*s \n ",v.decripta(v.cripta("ciao"))~"\0");
printf("ecco l' output di ciao criptato:\n%.*s \n ",v.cripta("ciao")~"\0");
printf("secondo oggetto\n");
printf("chiave usata:\n%.*s\n",w.m_key~"\0");
printf("cripta e decripta ciao\n%.*s \n ",w.decripta(w.cripta("ciao"))~"\0");
printf("ecco l' output di ciao criptato:\n%.*s \n ",w.cripta("ciao")~"\0");
return 0;
}
Riepiligo:
siamo partiti da un sorgente c che fa' qualche operazione matematica e lo abbiamo convertito in d,
ne abbiamo creato la funzione inversa e
abbiamo creato un oggetto che inglobi i 2 metodi
infine abbiamo espanto l' oggetto tramite l' aggiunta di un costruttore per generalizzare l'oggetto..