Bitmask: ازاي رقم واحد بيخزّن صلاحيات كتير ويفحصها في خطوة واحدة
المستوى: مبتدئ. الشرح ده مبني على فرضية إنك تعرف المتغيرات والشروط في أي لغة، ومش لازم تكون عارف النظام الثنائي قبل كده. هنبدأ بمثال بسيط، وبعدين نفك المفهوم علميًا.
لو خلّصت المقال ده هتعرف تخزّن 10 صلاحيات بوولين في عمود رقم واحد بدل 10 أعمدة، وتفحص أي صلاحية منهم في عملية واحدة. ده بالظبط اللي بيخلّي chmod 755 يلخّص 9 صلاحيات في 3 أرقام.
المشكلة باختصار
تخيّل عندك جدول مستخدمين، وكل مستخدم ليه صلاحيات: يقرأ، يكتب، يحذف، يدير، يصدّر تقارير... وهكذا. الطريقة الشائعة إنك تعمل عمود بوولين لكل صلاحية. الطريقة دي بتفشل لما الصلاحيات تكبر: 30 صلاحية يبقى 30 عمود، وكل migration جديد معناه عمود جديد وتعديل في الكود في كذا مكان. Bitmask بيحل ده بفكرة واحدة: خزّن كل الصلاحيات في رقم صحيح واحد.
مثال قبل النظرية: صف لمبات
تخيّل عندك صف فيه 3 لمبات على الحيطة. كل لمبة إما مولّعة (1) أو مطفية (0). لو قرأت الصف من الشمال لليمين، حالة اللمبات ممكن تتكتب كرقم: مثلاً مولّعة - مطفية - مولّعة يبقى 101.
دلوقتي سمِّ كل لمبة باسم صلاحية: اللمبة الأولى "قراءة"، التانية "كتابة"، التالتة "تنفيذ". الرقم 101 معناه: عنده قراءة، ماعندوش كتابة، عنده تنفيذ. لمبة واحدة بتمثّل صلاحية واحدة، وحالة الصف كله رقم واحد. ده هو الـ Bitmask بالظبط: كل بِت (لمبة) بيمثّل صلاحية.
المفهوم علميًا: كل بِت صلاحية مستقلة
الكمبيوتر بيخزّن الأرقام في النظام الثنائي (binary)، يعني سلسلة من 0 و 1، كل خانة منهم اسمها bit. الرقم 6 بيتخزّن كـ 110، والرقم 5 كـ 101. Bitmask هو إننا نتعامل مع كل بِت كعَلَم (flag) مستقل بيقول "الصلاحية دي شغّالة ولا لأ".
عشان نشغّل ونفحص البِتات بنستخدم عمليات على مستوى البِت (bitwise):
- OR (
|) للدمج: بيشغّل أي بِت شغّال في أي من الطرفين. بنستخدمه عشان نضيف صلاحية. - AND (
&) للفحص: بيدّي 1 بس لو البِت شغّال في الطرفين. بنستخدمه عشان نسأل "هل الصلاحية دي موجودة؟". - NOT (
~) مع AND للسحب: عشان نطفّي صلاحية معيّنة.
الكود: دمج وفحص وسحب الصلاحيات
الكود ده شغّال على أي Python 3. خلّينا نعرّف 3 صلاحيات، كل واحدة بِت لوحدها (نفس ترتيب rwx):