السلام عليكم ورحمة الله وبركاته
في هذا الموضوع سأشرح طريقة عمل نظام صلاحيات بأستخدام المعاملات الثنائية حبيت استخدم في هذا الشرح اكثر من لغة برمجة حتى تعم الفائدة للجميع لأنني لاحظت بعض الاشخاص عندما يبني نظام صلاحيات يعمله بطريقة متعبه له وللبرنامج.
لو افترضت ان لدي 4 صلاحيات للاعضاء هي :
- اضافة موضوع
- حذف موضوع
- تعديل الموضوع
- تعليق على الموضوع
بالطريقة التقليدية ستقوم بعمل جدول للصلاحيات وستضيف حقل لكل صلاحية ، هذا الامر بسيط ويمكن السيطرة عليه لكن ماذا لو كان لديك 20 او 50 صلاحية بلا شك ستصبع العملية صعبه ومجهده ، لكن باستخدام المعاملات الثنائية يمكنك اضافة حتى 1000 صلاحية او اكثر ولا مشكلة عندك في ذلك.
الموضوع سهل لكن محتاج شوية تركيز و يجب ان تكون ملم بالنظام العشري و النظام الثنائي وتعرف كيف تحول من النظام العشري الى النظام الثنائي والعكس ، هذه النقطة سأفترض انك فاهمها اذا لم تكن عندك معرفة بها عليك بالبحث والقراءة عنها.
الشرح مجزء الى جزئين الجزء الاول سأوضح مفهوم المعاملات الثنائية وكيف نقارن بين قيمتين اما الجزء الثاني فهو المتعلق بنظام الصلاحيات اذا كانت عندك معرفة مسبقة بالمعاملات الثنائية وتستطيع حساب نتائج المقارنة فلأفضل الانتقال الى الجزء الثاني مباشرة .
المعاملات الثنائية
ببساطة هي عبارة عن مقارنة بين عددين او اكثر لكن يتم المقارنة من خلال الاعداد الثنائية بحيث يتم تجزئة كل عدد الى جزء ، كل جزء عبارة عن بت ويتم مقارنة البت مع ما يقابلة من بت في العدد الاخر بهذه الطريقة :
A : | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1
B : | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0
لاحظ من الشكل أعلاه ان كل بت يقابله بت في العدد الاخر بمعنى اخر ان كل بت في A يقابله بت في B
قيمة A هي 00001001 لو حولناها الى النظام العشري بتساوي 9
ايضا قيمة B هي 00001010 بالنظام العشري تساوي 10
للمقارنة بين البتات هناك اربع طرق هي ( AND - OR - XOR - NOT ) اعتقد ان هناك طرق اخرى مثل Shift وغيرها لكن ما سنحتاجه في موضوعنا هذا فقط هذه الاربع
المقارنة من خلال المعامل AND
يقصد بهذه المقارنة ان البت في A اذا كانت قيمته تساوي 1 والبت في B ايضا قيمته تساوي 1 او العكس ، يكون الناتج 1 ما عدا ذلك يكون 0
مثال :
A = 9
B = 10
A : | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1
B : | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0
------------------------------------
re: | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0
لاحظ اذا كان البتان المتقابلان قيمتهما تساوي 1 فأن الناتج يكون 1
ايضا لاحظ ناتج المقارنة بين قيمة A وقيمة B هو 00001000 لو حولناها الى النظام العشري بتكون 8، بمعنى اخر ان 9 & 10 = 8
يرمز للمعامل AND بالرمز & وهذا كود على المعامل AND
///* -——— PHP Code -——————- $a = 9; $b = 10; echo $a & $b; //* -——— C# Code -——————— int a = 9; int b = 10; int z = a & b; Console.WriteLine(z); //* -——— Java Code-—————— int a = 9; int b = 10; int z = a & b; System.out.println(z);
ناتج الكود بالاعلى سيكون العدد 8 واعتقد فاهم من وين جاءت الـ 8 اذا لم تفهما ارجع لشرح المعامل AND بالاعلى
المعامل OR
رمزه هو ( | ) و يقصد به انه اذا كانت قيمة البت في A تساوي 0 وكذلك القيمة في B تساوي 0 يكون الناتج 0 ما عدا ذلك يكون الناتج 1
مثال :
A = 9
B = 10
A : | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1
B : | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0
------------------------------------
re: | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1
الناتج من المثال السابق بالنظام الثنائي هو 00001011 وبالنظام العشري تساوي 11
وهذا مثال بالكود
//* -——— PHP Code -——————- $a = 9; $b = 10; echo $a | $b; //* -——— C# Code -——————- int a = 9; int b = 10; int z = a | b; Console.WriteLine(z); //* -——— Java Code -——————- int a = 9; int b = 10; int z = a | b; System.out.println(z);
المعامل XOR
رمزه ( ^ ) ويقصد به انه اذا كان البت في A يختلف عن البت في B فأن الناتج يكون 1 ما عدا ذلك يكون 0
مثال :
A = 9
B = 10
A : | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1
B : | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0
------------------------------------
re: | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1
سيكون الناتج 3 بالعشري و 00000011 بالثنائي
المعامل NOT
رمزه ( ~ & ) لاحظ ان هذا المعامل يأخذ رمزين ، هذا المعامل يأخذ قيمة عدد واحد فقط ويقارن بتاتها مع العدد الاخر، اي انه اذا كان البت في A
يساوي 1 والبت في B يساوي 0 يكون الناتج 1 اما العكس اذا كان بت B يساوي 1 و بت A يساوي 0 فان الناتج يكون 0
مثال
A = 9
B = 10
A : | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1
B : | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0
------------------------------------
re: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1
الناتج سيكون 1 بالعشري وبالثنائي ، وهذا مثال بالكود
//* -——— PHP Code -——————- $a = 9; $b = 10; echo $a & ~$b; //* -——— C# Code -——————- int a = 9; int b = 10; int z = a & ~b; Console.WriteLine(z); //* -——— Java Code -——————- int a = 9; int b = 10; int z = a & ~b; System.out.println(z);
الصلاحيات بأستخدام المعاملات الثنائية
بعد هذا الكلام الطويل كله الي شرحناه ندخل في صلب موضوعنا الي هو كيف نستخدم المعاملات الثنائية في تطبيقاتنا وبرامجنا وذكرت مثال عليها الي هو نظام الصلاحيات
اول حاجة سنستخدم مصفوفة الاضعاف الي هي هذه
1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , .........
هذه الأعداد تبدء من 1 وتضربه في 2 بينتج 2 نضربه في 2 بينتج 4 نضربه في 2 بينتج 8 وهكذا الى ما لا نهاية.
الان كل صلاحية تعبر عنها بعدد من المصفوفة بالاعلى ، كيف نعبر عنها عن طريق التالي
سوف اقوم بإنشاء مصفوفة للصلاحيات وسأضع فيها اربع صلاحيات فقط بإمكان وضع العدد الذي تريد من الصلاحيات من خلال الكود التالي :
//* -——— PHP Code -——————-
$Permissions = array(
'CanInsertPost' => 1,
'CanDeletePost' => 2,
'CanEditPost' => 4,
'CanComment' => 8
);
//* -——— C# Code -——————-
var Permissions = new Dictionary<string, int>();
Permissions["CanInsertPost"] = 1;
Permissions["CanDeletePost"] = 2;
Permissions["CanEditPost"] = 4;
Permissions["CanComment"] = 8;
//* -——— Java Code -——————-
Map<String, Integer> Permissions = new HashMap<String, Integer>();
Permissions.put("CanInsertPost", 1);
Permissions.put("CanDeletePost", 2);
Permissions.put("CanEditPost", 4);
Permissions.put("CanComment", 8);لاحظ في كود PHP استخدمت مصفوفة لان لغة PHP تعاملها سهل مع المصفوفات لكن في C# استخدمت Dictionary اما في Java استخدمت HashMap
لا يشترط ابدا ً ان تعملها بهذا الشكل لك الحرية في اختيار الطريقة المناسبة المهم ان تضع القيم حسب مصفوفة الاضعاف بالاعلى ، وبالتأكيد لو كنت تستخدم قاعدة بينات ستضع الصلاحيات في جدول لكن بنفس فكرة الاكواد بالاعلى.
حسنا ً بعد ان عملت الصلاحيات لنفترض الان ان لدي مستخدم سأمثله بمتغير وليكن اسمه userPermission وسأعطيه صلاحية ( الاضافة - الحذف - التعديل )
اضيف الصلاحيات بالكود التالي :
//* -——— PHP Code -——————-
$userPermission = $Permissions["CanInsertPost"] | $Permissions["CanDeletePost"] | $Permissions["CanEditPost"];
//* -——— C# Code -——————-
int userPermission = Permissions["CanInsertPost"] | Permissions["CanDeletePost"] | Permissions["CanEditPost"];
//* -——— Java Code -——————-
int userPermission = Permissions.get("CanInsertPost") | Permissions.get("CanDeletePost") | Permissions.get("CanEditPost");بعد تنفيذ الكود أعلاه، سيحمل المتغير userPermission القيمة 7. لكن لماذا 7؟ الجواب بسيط وهو: مجموع الأرقام في (CanInsertPost, CanDeletePost, CanEditPost) هو 7 (عشري). ثنائياً يكون 00000100
حسنا الان نأتي للتحقق من صلاحية المستخدم بأستخدم الكود التالي :
//* -——— PHP Code -——————-
if ( $userPermission & $Permissions['CanComment'] )
{
echo 'You can Comment';
}
else
{
echo 'You can not Comment';
}
//* -——— C# Code -——————-
if ((userPermission & Permissions["CanComment"]) > 0)
{
Console.WriteLine("You can Comment");
}
else
{
Console.WriteLine("You can not Comment");
}
//* -——— Java Code -——————-
if( (userPermission & Permissions.get("CanComment")) > 0)
{
System.out.println("You Can Comment");
}else
{
System.out.println("You Can not Comment");
}في حالة اردنا ان نضيف للمستخدم صلاحية معينة نعطيها اياها بالطريقة التالية
//* --------- PHP Code ----------------
$userPermission |= $Permissions['CanComment'];
//* --------- C# Code ----------------
userPermission |= Permissions["CanComment"];
//* --------- Java Code----------------
userPermission |= Permissions.get("CanComment");ولإلغاء الصلاحية نفس الكود الي بالاعلى بس نستبدل OR الى XOR بمعنى نستبدل رمز | الى ^
الى هنا انتهيت اتمنى ان اكون وفقت لإيصال الفكرة بالشكل المطلوب ، اعتقد ان موضوع المعاملات اذا كانت هذه اول مره تسمع عنه ممكن ما تفهمه بسهوله لكن اذا قريت عنه اكثر ستفهمه .
اسعد بأستفساراتكم وملاحظاتكم M.B.O