Bitwise rechten systeem limieten en alternatieven?
Ik ben erg geïnteresseerd in Acl achtige dingen voor mijn site. Ik heb deze redelijk oude tutorial bestudeerd.
http://www.phphulp.nl/php/tutorial/beveiliging/bitwise-rechten-systeem/633/
Ik had al vaker gehoord van bitwise rechten bepalen. Ik vond het echt geniaal uitzien, één simpel getal om heel veel te bepalen wat een gebruiker kan. Toen ik me er echt in ging verdiepen omdat ik het wilde gaan gebruiken, kwam ik de nadelen tegen. Zo werd er beweerd dat het uitmaakt of de code draait op een 32-bit of 64-bit systeem. Je zou dan maar iets van 32 rechten kunnen opslaan in een rechten getal (de bitmask). Dat vind ik eerlijk gezegd te weinig.
Ik vraag me dus af of dit probleem is op te lossen. Wat ook een nadeel is, is dat er een soort exponentiële groei zit in elk getal dat bij een recht/permissie hoort.
Voorbeeld:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$rightList = array(
"del_users" => 2, // 2 ** 1
"edit_username" => 4, // 2 ** 2
"edit_email" => 8, // 2 ** 3
"reset_pwd" => 16, // 2 ** 4
"change_pwd" => 32, // 2 ** 5
"edit_emailconfirm" => 64, // 2 ** 6
"view_users" => 128, // 2 ** 7
"move_users" => 256, // etc...
"logout_users" => 512,
"notice_users" => 1024,
"view_user_msgs" => 2048,
"view_userlist" => 4096,
"mail_users" => 8192,
"register_setting" => 16384,
"login_setting" => 32768,
"reset_pwd_setting" => 65536,
"edit_emails" => 131072
);
?>
"del_users" => 2, // 2 ** 1
"edit_username" => 4, // 2 ** 2
"edit_email" => 8, // 2 ** 3
"reset_pwd" => 16, // 2 ** 4
"change_pwd" => 32, // 2 ** 5
"edit_emailconfirm" => 64, // 2 ** 6
"view_users" => 128, // 2 ** 7
"move_users" => 256, // etc...
"logout_users" => 512,
"notice_users" => 1024,
"view_user_msgs" => 2048,
"view_userlist" => 4096,
"mail_users" => 8192,
"register_setting" => 16384,
"login_setting" => 32768,
"reset_pwd_setting" => 65536,
"edit_emails" => 131072
);
?>
Het valt ook wel weer mee, maar stel dat je 28 rechten hebt, 2^28 = 268435456. Dat is best een lange integer.
Maar goed. Het gaat me vooral om het 32/64 bit systeem probleem.
En verder vraag ik me af of er alternatieven zijn. Het hoeft alleen maar een manier te zijn waarmee je heel veel rechten kunt opslaan in één getal. Dat je bijvoorbeeld met een of andere formule weer uit dat getal kunt halen wat er precies wel en niet mag voor een user.
Gewijzigd op 18/11/2014 19:32:39 door Jan terhuijzen
Enkel de verwerkingssnelheid verschilt tussen een 32 bits en 64 bits machine.
Het verschil is dat een 64 bits machine 64 bits kan verwerken in 1 kloktikje (miljoenste van een seconde) en dat de 32 bits daar 2, 3 of 4 kloktikjes voor nodig heeft.
Een ander merkbaar verschil is de data die je verbruikt. als je 500.000 bestanden hebt waarvan je van ieder bestand 64 bits wilt reserveren voor de rechten dan verbruik je een kleine 4 megabyte en bij 32 bits maar de helft.
Jan terhuijzen op 18/11/2014 19:30:49:
Wat ook een nadeel is, is dat er een soort exponentiële groei zit in elk getal dat bij een recht/permissie hoort.
Voor een mens een nadeel, voor een computer veranderd er vrijwel niets.
Jan terhuijzen op 18/11/2014 19:30:49:
En verder vraag ik me af of er alternatieven zijn. Het hoeft alleen maar een manier te zijn waarmee je heel veel rechten kunt opslaan in één getal. Dat je bijvoorbeeld met een of andere formule weer uit dat getal kunt halen wat er precies wel en niet mag voor een user.
Ik denk niet dat er veel alternatieven zijn. een bit is het kleinste deel van het geheugen en kan enkel 0 of 1 zijn. (aan of uit). Er zijn natuurlijk compressie technieken maar dat heeft voor een paar bits (want het zijn er echt maar een paar) geen enkele zin.
Gewijzigd op 18/11/2014 23:31:25 door Frank Nietbelangrijk
Frank Nietbelangrijk op 18/11/2014 23:26:45:
Ik denk niet dat er veel alternatieven zijn. een bit is het kleinste deel van het geheugen en kan enkel 0 of 1 zijn. (aan of uit). Er zijn natuurlijk compressie technieken maar dat heeft voor een paar bits (want het zijn er echt maar een paar) geen enkele zin.
Oke, bedankt voor de reactie.
Met een alternatieve manier bedoelde ik eigenlijk niet meer met bits werken, maar gewoon met getallen. Dus rekenen en doen alsof de getallen op papier staan, zonder het bestaan van bits. Maar ook daar heb ik al over nagedacht en ik kan niet echt iets verzinnen.
Maar op de bitwise manier: hoeveel rechten zou ik dan kunnen opslaan in een gewone integer? Vanaf wanneer kan ik problemen krijgen dat het niet meer past?
Gewijzigd op 19/11/2014 15:35:53 door jan terhuijzen
Je kunt net zoveel rechten setten of clearen als het aantal bits dat de integer groot is. Met andere woorden kun je in een 16 bits integer 16 rechten kwijt, in een 32 kun je 32 rechten kwijt enz.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
function getBinary($integer)
{
return str_pad(decbin($integer), 8, '0', STR_PAD_LEFT);
}
// rechten definieren
define('R_READ', 0x01); // 00000001
define('R_WRITE', 0x02); // 00000010
define('R_DELETE', 0x04); // 00000100
define('R_EXECUTE', 0x08); // 00001000
// nieuwe variabele aanmaken met READ en WRITE rechten
$rechten = R_READ | R_WRITE;
echo getBinary($rechten) . '<br>';
// DELETE rechten toevoegen aan een variabele
$rechten |= R_DELETE;
echo getBinary($rechten) . '<br>';
// WRITE rechten verwijderen uit een variabele
$rechten ^= R_WRITE;
echo getBinary($rechten) . '<br>';
// En zo kun je testen of DELETE aan of uit staat
if($rechten & R_DELETE)
{
echo 'Delete is toegestaan<br>';
}
else
{
echo 'Delete is verboden<br>';
}
?>
function getBinary($integer)
{
return str_pad(decbin($integer), 8, '0', STR_PAD_LEFT);
}
// rechten definieren
define('R_READ', 0x01); // 00000001
define('R_WRITE', 0x02); // 00000010
define('R_DELETE', 0x04); // 00000100
define('R_EXECUTE', 0x08); // 00001000
// nieuwe variabele aanmaken met READ en WRITE rechten
$rechten = R_READ | R_WRITE;
echo getBinary($rechten) . '<br>';
// DELETE rechten toevoegen aan een variabele
$rechten |= R_DELETE;
echo getBinary($rechten) . '<br>';
// WRITE rechten verwijderen uit een variabele
$rechten ^= R_WRITE;
echo getBinary($rechten) . '<br>';
// En zo kun je testen of DELETE aan of uit staat
if($rechten & R_DELETE)
{
echo 'Delete is toegestaan<br>';
}
else
{
echo 'Delete is verboden<br>';
}
?>
Toevoeging op 19/11/2014 19:34:25:
Tip: vergelijk die bits gewoon met een dipswitch:
Gewijzigd op 19/11/2014 19:31:02 door Frank Nietbelangrijk
dec2bin en bin2dec? :)
PS, zie ook: http://www.phphulp.nl/php/tutorial/berekeningen/bitwise-php/756/
Frank, 0x bestaat volgens mij niet als prefix in PHP. Gewoon 1, 2, 3, 4 is goed genoeg. En weet je van het bestaan van PS, zie ook: http://www.phphulp.nl/php/tutorial/berekeningen/bitwise-php/756/
Gewijzigd op 19/11/2014 19:45:52 door Wouter J
De 2 moet weg bij die functions.
Het is gewoon decbin en bindec, etc.
Ook de 0x bestaat.
Van php.net:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
$a = 0b11111111; // binary number (equivalent to 255 decimal)
?>
$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
$a = 0b11111111; // binary number (equivalent to 255 decimal)
?>
Gewijzigd op 19/11/2014 20:06:27 door - SanThe -
Het moet volgens mij decbin() en bindec() zijn? kan die andere niet vinden. Daarnaast vul ik ze aan met voorloop nullen zodat ze altijd acht cijfers lang zijn om het voorbeeld te verduidelijken. en inderdaad gewoon 1, 2, 4, 8 is genoeg. Maar in in PHP bestaat de 0x en 0b prefix wel degelijk Wouter:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
$a = 0b11111111; // binary number (equivalent to 255 decimal)
?>
$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
$a = 0b11111111; // binary number (equivalent to 255 decimal)
?>
bron: http://php.net/manual/en/language.types.integer.php
Toevoeging op 19/11/2014 20:08:04:
verder is je eigen schrijfwijze natuurlijk een eigen voorkeur.
Uiteindelijk is dit allemaal hetzelfde:
(Dit zegt waarschijnlijk ook weer iets of de server waarop ik het online testte een 32 of 64-bit systeem heeft).
Maar ik zoek dus een manier om meer rechten op te slaan, en ook graag systeem onafhankelijk.
In welke taal heb je dat geschreven Jan?
Jan terhuijzen op 19/11/2014 20:08:40:
Ik kon in één integer 63 rechten kwijt.
Vergeet niet dat het 0 t/m 63 is.
Verder zitten er dubbelingen in je rechten die onlogisch lijken, bijvoorbeeld:
- reset_pwd
- change_pwd
- reset_pwd_setting
@Ward Ja tegenstrijdige rechten had ik ook al aan gedacht. Maar reset_pwd is een gebruiker zijn wachtwoord via email resetten, change_pwd is het echt veranderen door het in te vullen (zelf wachtwoord verzinnen voor iemand, maar oké)
en reset_pwd_setting betekend dat je aan/uit kunt zetten dat van buitenaf de wachtwoord-vergeten optie kan worden gebruikt. (Ook misschien wel raar, wordt er waarschijnlijk uitgehaald)
Ik had ook al gedacht om gewoon groepen te maken met de rechten die bij elkaar horen. Of niet alleen boolean achtige rechten, maar bij sommige rechten meerdere mogelijke waarden. Bijvoorbeeld bij iets als Contact form de opties:
- Geen toegang tot de berichten
- Alleen lezen
- Lezen en antwoorden
- Lezen, antwoorden, verwijderen
Gewijzigd op 19/11/2014 20:33:03 door jan terhuijzen