Fiind necesară setarea/verificarea permisiunilor pentru utilizatorii unei aplicatii,
si presupunând că informatiile legate de permisiune (per utilizator) pot fi
salvate doar într-o variabilă de dimeniunea unui octet (limitari de memorie), să
se implementeze functii pentru setarea si verificarea permisiunilor unui anumit
utilizator. Există 5 tipuri de permisiuni:Read/Write/Delete/Rename/Copy.
andreea0201user (0)
Ai 5 permisiuni: Read,Write,Delete,Rename,Copy.
Un utilizator poate avea cate o stare asociata pentru fiecare din permisiune.
bitul 1-Daca e activa
bitul 0-Daca nu e activa
astfel daca ai 5 permisiuni => ai nevoie in total de 5 biti pentru a reprezenta toate cele 2^5 combinatii posibile.
Exemplu. Utilizator care are read, nu are write, are delete, nu are rename si are copy => 10101 este codul asociat permisiunilor.
El poate fi reprezentat si in baza 10 ca numarul 21.
In marea majoritate a cazurilor adresarea se face pe un numar minim de 8 biti, adica un byte. deci nu poti sa folosesti doar 5 biti, trebuie sa reprezinti codul pe 8(efectiv masina nu are adresa catre un singur bit sau grupuri de cate 2 sau 3 sau etc. Are doar catre 8 cel putin. Din cauza asta problema cere pe 8 biti si nu 5 cum am dori…).
Poti prefixa codul tau cu inca 3 biti de 0 redundanti. Asa ca vei reprezenta cele 2^5 combinatii in numere de la 00000000 la 00011111. In baza 10 inseamna numere de la 0 la 31.
Daca vrei sa verifici daca utilizatorul are permisiunea x, atunci faci o masca de 8 biti ce are pe bitul x 1 si 0 in rest.
ex:
Pt: |Read|Write|Delete|Rename|Copy|
Read: 10000
Write: 01000
Delete: 00100
Rename:00010
Copy:00001
Care vor fi in mod evident prefixati de cei 3 biti de 0 redundanti.
In momentul in care faci verificarea pentru o anumita permisiune, faci un SI logic intre codul de permisiuni asociat utilizatorului, si masca.
Ex:
Pt: 000|10101 care spune ca are read, NU are write, ARE delete, NU are rename, ARE copy.
Daca vrei sa verifici daca utilizatorul are read, faci un SI logic intre:
000|10101
SI
000|10000
=>00010000 care este diferit de 0 deci are read.
Daca vrei sa verifici daca utilizatorul are write, faci SI logic intre:
000|10101
SI
000|01000
=>00000000 care este 0 => utilizatorul NU are write.
Verificarea pentru fiecare componenta in parte se reduce la a verifica daca rezultatul operatiei de SI logic pe biti este sau nu 0.
Vezi tu, mastile astea pot arata in fel si chip si pot fi combinate cu o gramada de operatii logice si astfel ai puterea de a selecta ce biti vrei tu din interiorul byte-ului si in ce mod sau logica doresti.
exemple:
„Toate permisiunile pe care NU le are utilizatorul”
„Verifica pe biti daca are read, nu are write si daca are write sa nu aiba rename si bla bla bla” sau tot felul de idiotenii cumplite…
In enunt nu cred ca cerea mai mult decat ti-am prezentat eu avand in vedere ca e vorba de o problema de liceu.
Pentru setarea permisiunilor exista mai multe metode.
Una din ele ar fi sa te folosesti de shiftare la stanga pentru a seta bitii corespunzatori.
Exemplu:
iei un char var_permisiune; //care e reprezentat pe 8 biti
il initializezi cu 0. => in memorie arata asa: 00000000
si:
Pentru fiecare tip de permisiune in parte: read,write etc.
Daca ai read sa zicem, shiftezi var_permisiune cu un bit la stanga si apoi aduni 1.
adica:
var_permisiune=00000000
Ai read? =>DA
shift stanga => var_permisiune=00000000(ramane la fel)
var_permisiune=00000000+1=00000001
In continuare:
Ai write? sa zicem ca DA
=>
shift stanga-> var_permisiune=00000010
var_permisiune=var_permisiune+1=00000011
In cazul in care NU aveai write, faceai doar shiftare la stanga si treceai mai departe(adica nu mai adunai 1).
Ai write? => NU
shift_stanga=>var_permisiune=00000100
Si aplici procedura pentru fiecare componenta in parte.
Daca ai permisiunea curenta => shiftezi la stanga si aduni 1
Daca NU ai permisiunea curenta => shiftezi la stanga si atat
Pt operatii pe biti, in C pentru SI logic intre 2 variabile folosesti operatorul: „&”
ex: rezultat=var1&var2;//realizeaza SI logic intre bitii lui var1 si bitii lui var2 si pune rezultatul operatiei in variabila.. rezultat
spre exemplu:
var1=00001101(in baza 2)=13(in baza 10)
var2=00001010(in baza 2)=10(in baza 10)
var1&var2=00001001(in baza 2)=9(in baza 10)
Pt shiftare la stanga te folosesti de: „<<„
ex: var=3;
var=var<<1;//shifteaza la stanga cu un bit
=> var va fi acum 6
In memorie var arata asa: 00000010.
dupa shiftare, var arata asa: 00000100.
Bun,
Daca ai setat deja premisiunile unui utilizator, si vrei sa le updatezi(spre exemplu cum aveam acolo permisiunea 00010101) si vrei ca de data asta permisiunea write sa fie setata, faci SAU logic intre masca lui write si permisiune.
In general cand lucrezi pe biti nu prea esti niciodata interesat de valoarea in baza 10, te intereseaza doar reprezentarea in binar. Traducerea in baza 10 rareori ai putea s-o folosesti pentru ceva anume.
O exceptie care aduce sens valorii in baza 10 atunci cand lucrezi pe biti ar fi spre exemplu daca vrei sa inmultesti un numar cu 2 pentru ca o shiftare cu un bit mai la stanga, ca rezultat are exact acelasi efect cu a-l inmulti cu 2 insa in interior, o shiftare la stanga se realizeaza mult mai rapid decat o inmultire cu 2 deoarece este o operatie mai usoara pentru procesor(pentru o amarata de inmultire procesorul face o groaza de minuni ca sa ajunga la rezultat dar pentru o shiftare doar… ii da putin mai incolo…)
Regula e valabila pentru orice operatie de inmultire cu o constanta care se poate reprezenta ca putere a lui 2.