Fino ad ora tutto il codice che abbiamo scritto era in
un blocco solo, ovvero abbiamo scritto tutte le righe una dietro
l'altra, ma solo perché gli esempi visti erano semplici, ma capita e
anche sovente di dover scrivere pezzi di codice che serve
riutilizzare. Le motivazioni possono essere molteplici, ma sovente
conviene utilizzare le procedure e le funzioni piuttosto che scrivere
un monoblocco di codice. Ipotizziamo di dover invertire il valore di
due variabili di nome Valore1 e Valore2 e di dover effettuare questa
operazione sovente all'interno del nostro programma, per poter fare
questa operazione abbiamo bisogno anche della variabile di nome
Valore3. Vediamo ora come andrebbe scritto il codice che effettua
l'inversione dei valori:
Valore3:=Valore1;
Valore1:=Valore2;
Valore2:=Valore3;
Bene ora immaginiamo di doverlo scrivere 10, 100, 1000
volte all'interno del codice, possiamo facilmente capire che il
codice in questione diverrà molto lungo, quindi difficile da gestire
in un secondo momento, e in più il programma diverrebbe molto grosso
senza tenere conto che la variabile di nome Valore3 rimarrebbe
allocata in memoria per tutta l'esecuzione del programma. Mentre ora
immaginiamo di immettere questo codice scritto in una procedura, le
migliorie sono diverse, ad esempio quando la procedura ha finito la
sua vita la variabile Valore3 viene deallocata, il programma occupa
meno spazio e se bisogna fare manutenzione il codice diventa più
leggibile.
Bene fino ad ora abbiamo parlato di procedure e funzioni
come se fossero la stessa cosa, ma fondamentalmente c'è una
differenza tra le due cose, ovvero che le funzioni restituiscono un
valore, mentre le procedure no. Vediamo ora come si dichiara una
procedura e come si dichiara una funzione. Procedura:
procedure
NomeProcedura();
begin
.
.
.
end;
Funzione:
function
NomeFunzione(): tiporestituito;
begin
.
.
NomeFunzione:=valorerestituito;
end;
La prima cosa che bisogna notare è che sia le funzioni
che le procedure hanno un nome che le contraddistingue, per seconda
cosa bisogna notare che entrambe terminano con le parentesi e con il
punto e virgola. Ma le due cose più importanti da notare sono che la
funzione per restituire un valore deve specificare di che tipo è, e
per effettuare la restituzione bisogna attribuire il valore da
restituire al nome della funzione stessa.
Un altra cosa da apprendere quando si tratta l'argomento
procedure e funzioni è il passaggio di parametri. Per passaggio di
parametri si intende il passare delle informazioni alla procedura o
alla funzione. Vediamo un esempio concreto:
Bene come si può notare, all'interno delle parentesi
tonde subito dopo il nome della procedura, è presente la
dichiarazione di tre variabili intervallate da dei punti e virgola.
In questo modo definisco quanti parametri passare alla
funzione/procedura specificando il tipo del dato che gli passo.
I parametri possono essere passati in due modi, per
valore o per referenza. La differenza tra le due è che se sono
passati per valore, il valore stesso non può essere modificato
all'esterno della procedura, se invece il parametro è passato per
referenza allora il valore se viene modificato verrà modificato
sempre nel programma. In pratica i due tipi si differenziano grazie
alla parola riservata var all'interno delle parentesi tonde. Vediamo
un esempio di passaggio di parametri per valore:
procedure
Inverti(var Valore1: integer; var Valore2: integer);
e ricompilare. Una volta eseguite entrambe le versioni è
evidente la differenza tra le due.
N.B.: se per caso si immettesse la riga procedure
Inverti(Valore1: integer; var Valore2: integer); allora
Valore1 sarebbe passato per valore e Valore2 per referenza.
Le strutture sono dei tipi di variabile composte da
variabile semplici, ipotizziamo di voler descrivere un animale con
una variabile, dovremmo stabilire che tipo di animale è, quanti anni
di vita ha, e tutta una serie di altri fattori. Bene con i mezzi fino
ad ora acquisiti, dovremmo fare tutto ciò con due o più variabili,
dipende dal numero di caratteristiche che si vogliono far avere
all'animale; con una struttura è possibile fare ciò con una
variabile. Vediamo ora come si dichiara una struttura:
type
nomedadareallastruttura=record
caratteristica1:
tipovariabile;
caratteristica2:
tipovariabile;
.
.
.
caratteristicaN:
tipovariabile;
end;
Ora che sappiamo come si dichiara una struttura dobbiamo
anche sapere che si posiziona subito dopo altre eventuali strutture
già dichiarate o dopo l'inclusione delle librerie, ovvero dopo la
sezione USES. Vediamo ora l'esempio di cui parlavamo poco sopra,
ovvero della variabile che identifica l'animale, io ho usato solo 2
caratteristiche, razza e anni. Le parti importanti sono sottolineate.
La prima cosa che dovrebbe saltare all'occhio come già
detto prima è il posizionamento della dichiarazione della struttura,
ovvero la prima parte sottolineata. La seconda cosa da notare è che
una volta definita la struttura dobbiamo dichiarare delle variabili
con tipo di variabile la struttura stessa, ovvero la seconda parte
sottolineata. La terza cosa da capire è che per accedere alle
singole caratteristiche della struttura si usa il punto, sia per
valorizzarlo che per leggerlo, esattamente come nel terzo blocco
sottolineato nell'ultimo esempio.
Vediamo ora un altro tipo di dato non molto utilizzato,
ma che può risultare comodo in alcune occasioni: gli insiemi, che in
Pascal sono molto simili al concetto di insieme in matematica; dato
un insieme A di oggetti di un insieme di dati B, ogni oggetto di B
appartiene o non appartiene ad A.
Vediamo come dichiarare gli insiemi con un esempio:
var giorni: SET OF integer;
Possiamo altrimenti scrivere:
type giorniLavorativi: SET OF integer;
var giorniRip : giorniLavorativi;
Ma il risultato è lo stesso. Per inizializzare un
insieme usiamo la sintassi:
giorniLavorativi := [1,3..7, 10..25, 29];
giorniRip := []; {insieme vuoto}
Si noti l'uso di un range nell'assegnazione. La sintassi
generale è quindi per un insieme [el1, el2, el3..el7, …] dove per
elN si intende elemento numero.
Le operazioni fattibili con gli insiemi sono le stesse
in matematica: ad esempio, "+" corrisponde all'unione, "-"
alla differenza e "*" all'intersezione.
[1, 3, 4] + [3, 9..11] = [1, 3, 4, 9..11]
[5, 7, 19, 22] - [22] = [5, 7, 19]
[5, 7, 19, 22] - [23] = [5, 7, 19, 22]
[11..22] * [15..56] = [15..22]
[11..22] + [15..56] = [11..56]
[5, 7, 19, 22] * [22] = [22]
[5, 7, 19, 22] * [23] = []
Per verificare se un elemento è in un insieme, usiamo
l'operatore IN:
if
1 in giorniLavorativi then
È possibile anche confrontare gli insiemi:
1. =: restituisce true se i due insiemi sono uguali;
2. <>: restituisce true se i due insiemi sono
diversi;
3. <=: restituisce true se il primo insieme è
sottoinsieme del secondo (il secondo contiene il primo);
Turbo Bird è uno strumento di amministrazione per Firebird. Vi permette di creare nuovi database Firebird, creare / modificare tabelle, procedure, viste, triggers, generatori, ruoli, funzioni definite dall'utente, domini e molto altro.Turbo Bird è molto facile da installare e ci sono versioni per Linux a 32 bit, Windows a 32 bit, e i binari per MacOS. È possibile installare il sorgente e compilarlo con Lazzarus in qualsiasi altra piattaforma che è supportata da Lazarus.
PeaZip è un gestore di archivi Open Source ed è flessibile, portabile, sicuro e libero.
Permette di estrarre, creare e convertire archivi multipli allo stesso tempo,
creare archivi autoestraenti, split / join, supporta la crittografia e molto altro.
http://www.peazip.org/
Interfaccia grafica facile da usare, supporta il Drag & Drop e si integra nel menu contestuale del sistema
Tutto in uno strumento per lavorare con tutti i formati di archivio più
importanti: estrarre, comprimere, convertire, criptare, cancellare, salvare gli script di backup ...
Grande velocità, rapporto di compressione elevato, una migliore
stabilità e sicurezza con comprovata tecnologia 7-Zip Open Source
Correre in tutte le versioni di Windows, da 9x a 7, e dispone della versione a 64 bit per migliori prestazioni su sistemi a 64 bit, esiste inoltre una versione portatile che non ha bisogno di essere installata e può essere eseguito da unità USB, e da versioni di Linux con la stessa interfaccia grafica.
Written by xinyimanposted in Lazarus 1.0 Ottobre 21, 2011, 11:09:00 am22359 ViewsRating: 0 (0 Rates)Print
Cosa succede quando avete finito un software e volete distribuirlo, previa vostra autorizzazione? Questo How To vi viene incontro e vi spiega come io ho affrontato il problema.
La soluzione a tale problema è composta di due parti, un codice php posizionato nel sito dal quale distribuisco il software e dal quale faccio fare l'attivazione del prodotto.
Quella che segue è la classe PHP che mi genera il mio codice di attivazione nel formato: XXXX-XXXX-XXXX-XXXX
[code]
/*
Classe realizzata da Sammarco Francesco
Es:
$OggettoSN = new Serial_Number;
$CodSer = $OggettoSN->PKV_MakeKey($IdCod);
*/
class Serial_Number
{
// Costruttore
function __construct()
{
}
// Distruttore
public function __destruct()
{
//non faccio niente
}
private function Shr($a, $b)
{
return ($a/(2^$b));
}
type
SerialNumber=object
private
public
function PKV_GetKeyByte(const Seed : Int64; a, b, c : Byte) : Byte;
function PKV_CheckKey(const S : String) : Integer;
function PKV_CheckKeyChecksum(const Key : String) : Boolean;
function PKV_MakeKey(const Seed : Int64) : String;
function PKV_GetChecksum(const s : String) : String;
end;
var
BL : array[0..0] of String = ('11111111');
implementation
{ serial number }
function StartsStr(str: string; inizio: string): boolean;
var
Esci: boolean;
ret: boolean;
i: integer;
len1: integer;
len2: integer;
begin
len1:=length(str);
len2:=length(inizio);
ret:=false;
if len1>=len2 then
begin
i:=0;
ret:=TRUE;
if len1=0 then
Esci:=TRUE
else
Esci:=FALSE;
while (Esci=False) do
begin
if str[i]<>inizio[i] then
begin
Esci:=TRUE;
ret:=FALSE;
end;
Inc(i);
if i>len1 then
Esci:=TRUE;
end;
end;
StartsStr:=ret;
end;
function SerialNumber.PKV_GetKeyByte(const Seed : Int64; a, b, c : Byte) : Byte;
var
risultato: byte;
begin
a := a mod 25;
b := b mod 3;
if a mod 2 = 0 then
risultato := ((Seed shr a) and $000000FF) xor ((Seed shr b) or c)
else
risultato := ((Seed shr a) and $000000FF) xor ((Seed shr b) and c);
PKV_GetKeyByte:=risultato;
end;
function SerialNumber.PKV_GetChecksum(const s : String) : String;
var
left, right, sum : Word;
i : Integer;
app: string;
begin
left := $0056;
right := $00AF;
if Length(s) > 0 then
for i := 1 to Length(s) do
begin
right := right + Byte(s[i]);
//app:= app + 'r: ' + s[i] + '(' + IntToStr(Byte(s[i])) + ')';
//right := right + Byte(s[i]);
if right > $00FF then
Dec(right, $00FF);
Inc(left, right);
if left > $00FF then
Dec(left, $00FF);
end;
sum := (left shl 8) + right;
result := IntToHex(sum, 4);
end;
function SerialNumber.PKV_MakeKey(const Seed : Int64) : String;
var
KeyBytes : array[0..3] of Byte;
i : Integer;
app: string;
begin
// Fill KeyBytes with values derived from Seed.
// The parameters used here must be extactly the same
// as the ones used in the PKV_CheckKey function.
// A real key system should use more than four bytes.
KeyBytes[0] := PKV_GetKeyByte(Seed, 24, 3, 200);
KeyBytes[1] := PKV_GetKeyByte(Seed, 10, 0, 56);
KeyBytes[2] := PKV_GetKeyByte(Seed, 1, 2, 91);
KeyBytes[3] := PKV_GetKeyByte(Seed, 7, 1, 100);
// the key string begins with a hexidecimal string of the seed
result := IntToHex(Seed, 8);
// then is followed by hexidecimal strings of each byte in the key
for i := 0 to 3 do
begin
result := result + IntToHex(KeyBytes[i], 2);
end;
// add checksum to key string
result := result + PKV_GetChecksum(result);
// Add some hyphens to make it easier to type
i := Length(result) - 3;
while (i > 1) do
begin
Insert('-', result, i);
Dec(i, 4);
end;
end;
function SerialNumber.PKV_CheckKeyChecksum(const Key : String) : Boolean;
var
s, c : String;
begin
result := False;
// remove cosmetic hypens and normalize case
s := UpperCase(StringReplace(Key, '-', '', [rfReplaceAll]));
if Length(s) <> 20 then
exit; // Our keys are always 20 characters long
// last four characters are the checksum
c := Copy(s, 17, 4);
SetLength(s, 16);
// compare the supplied checksum against the real checksum for
// the key string.
result := c = PKV_GetChecksum(s);
end;
function SerialNumber.PKV_CheckKey(const S : String) : Integer;
var
Key, kb : String;
Seed : Int64;
i : Integer;
b : Byte;
begin
result := KEY_INVALID;
if not PKV_CheckKeyChecksum(S) then
exit; // bad checksum or wrong number of characters
// remove cosmetic hypens and normalize case
Key := UpperCase(StringReplace(S, '-', '', [rfReplaceAll]));
// test against blacklist
if Length(BL) > 0 then
for i := Low(BL) to High(BL) do
if StartsStr(BL[i], Key) then
begin
result := KEY_BLACKLISTED;
exit;
end;
// At this point, the key is either valid or forged,
// because a forged key can have a valid checksum.
// We now test the "bytes" of the key to determine if it is
// actually valid.
// When building your release application, use conditional defines
// or comment out most of the byte checks! This is the heart
// of the partial key verification system. By not compiling in
// each check, there is no way for someone to build a keygen that
// will produce valid keys. If an invalid keygen is released, you
// simply change which byte checks are compiled in, and any serial
// number built with the fake keygen no longer works.
// Note that the parameters used for PKV_GetKeyByte calls MUST
// MATCH the values that PKV_MakeKey uses to make the key in the
// first place!
result := KEY_PHONY;
// extract the Seed from the supplied key string
if not TryStrToInt64('$' + Copy(Key, 1, 8), Seed) then
exit;
{$IFDEF KEY00}
kb := Copy(Key, 9, 2);
b := PKV_GetKeyByte(Seed, 24, 3, 200);
if kb <> IntToHex(b, 2) then
exit;
{$ENDIF}
{$IFDEF KEY01}
kb := Copy(Key, 11, 2);
b := PKV_GetKeyByte(Seed, 10, 0, 56);
if kb <> IntToHex(b, 2) then
exit;
{$ENDIF}
{$IFDEF KEY02}
kb := Copy(Key, 13, 2);
b := PKV_GetKeyByte(Seed, 1, 2, 91);
if kb <> IntToHex(b, 2) then
exit;
{$ENDIF}
{$IFDEF KEY03}
kb := Copy(Key, 15, 2);
b := PKV_GetKeyByte(Seed, 7, 1, 100);
if kb <> IntToHex(b, 2) then
exit;
{$ENDIF}
// If we get this far, then it means the key is either good, or was made
// with a keygen derived from "this" release.
result := KEY_GOOD;
end;
end.
[/code]
Quello che è importante è che i valori numerici della funzione PKV_GetKeyByte siano valorizzati in maniera identica con quelli del codice PHP
Per poter sfruttare questa libreria bastano poche linee di codice in free pascal
if length(Codice)=24 then
begin
Valore:=MioOggetto.PKV_CheckKey(Codice);
if Valore=0 then
begin
{CODICE DI ATTIVAZIONE VALIDO}
end;
end;
Dove la variabile Codice è valorizzata con il codice che precedentemente avevamo comunicato al nostro cliente.
Bene questa è la soluzione che avevo usato io in uno dei miei progetti. Se avete altre soluzioni non esitate a comunicarmele e vedrò di pubblicarle. Avverto che pubblicherò solo soluzioni che possono essere multipiattaforma.
Questo blog non rappresenta una testata giornalistica poiché viene
aggiornato senza alcuna periodicità. Non può pertanto considerarsi un
prodotto editoriale ai sensi della legge n. 62/2001.
Questo sito utilizza cookie, anche di terze parti, per offriti servizi in linea con le tue preferenze. Chiudendo questo banner, scorrendo questa pagina, cliccando su un link o proseguendo la navigazione in altra maniera, acconsenti all’uso dei cookie.