יום שלישי, 2 ביולי 2013

Bitwise Guide




אחד התחומים הותיקים בעולם הפיתוח והאלקטרוניקה, סביר להניח שרובנו לא נתעסק איתו ביום יום אבל עדיין כדאי לעשות איזה רענון, החלטתי לסכם את הנושא ולהביא מספר דוגמאות עבור מי שהספיק לשכוח או למי שאף פעם לא נגע.

Binary

שיטת ספירה ותיקת ימים הרבה לפני עידן המחשבים שמאפשרת לתת לכל מספר ערך מייצג המורכב מ 0 ו 1 בעזרת מכפלה ב 2, יופי טופי , אבל תכלאס מה היה אפשר לעשות עם זה בעת העתיקה או במאה 17, מסתבר שדווקא במאה ה 20 נמצא לזה שימוש רציני יותר ששינה את האנושות למה שאנחנו מכירים היום, היכולת לייצג כל מספר כערך בינארי הוא אבן יסוד בעולם האלקטרוניקה כי הוא מתורגם בסופו של דבר למתג חשמלי שמאפשר לנו לשלוט בזרם בלוח ובעולם התוכנה מתורגם ל Bit שמרכיב את כל הטיפוסים האחרים שאיתם עובדים כמו  INT \ CHAR \ BYTE וכדומה, ניתן לשמור אותו על זיכרון או כונן קשיח.



שימו לב
  •  ה Bit הראשון מייצג אם המספר יהיה זוגי או אי זוגי.
  • 2 מושגים שכדאי להכיר Big Indian,Small Indian שקובעים את סדר הבתים. 

BitWise

"חוכמת הבתים" היא למעשה אוסף של Operators שמאפשרים לשנות ערך בעזרת משחק ע"ג הבתים שהוא מכיל, אפשר לומר שהם הכלים הראשונים לכתיבת קוד ולבצע פעולות על המעבד זו תורה שלמה שנסתרת מהעין במיוחד שהיום יש שפות פיתוח עשירות שכמעט אין בזה צורך ,אבל עדיין ניתן לראות שימוש רחב ב Bitwise בעולם ה Embedded ,אבטחת מידע ובהמון תחומים נוספים.


ShiftLeft

סימון ה Operator הוא >> , מזיז את כל הבתים שמאלה כפי שניתן לראות בדוגמה מזיזים את הערך 10 בית אחד שמאלה ומקבלים את תוצאת הכפל בין 10 ל 2.


static void shiftLeft()
{
            //add one bit from right
            byte a = 10;
            // binary equivalent for 10 is 1010
            Console.WriteLine("Original " + Environment.NewLine
                + " A Number: " + a + " Binary: " + Convert.ToString(a, 2));

            long result = a << 1;

            Console.WriteLine("Results - Number: " + result
                + " Binary: " + Convert.ToString(result, 2));
}



ShiftRight

סימון ה Operator הוא << , מזיז את כל הבתים ימינה כפי שניתן לראות בדוגמה מזיזים את הערך 10 בית אחד ימינה ומקבלים את תוצאת החילוק בין 10 ל 2.




  static void shiftRight()
  {
            //remove one bit from right
            byte a = 10;
            // binary equivalent for 10 is 1010
            Console.WriteLine("Original " + Environment.NewLine
                + " A Number: " + a + " Binary: " + Convert.ToString(a, 2));

            long result = a >> 1; 

            Console.WriteLine("Results - Number: " + result
                + " Binary: " + Convert.ToString(result, 2));
   }


AND

סימון ה Operator הוא & , כפי שניתן לראות בדוגמה במקרה שברצף הבתים בערך הראשון יש בתים המוגדרים כ  False - 0  באותו מיקום בערך השני נדרסים הבתים שמוגדים כ True- 1.



   static void exampleAND()
   {
            // operator rules
            //1 on 0 = 0
            //0 on 1 = 0
            //0 on 0 = 0
            //1 on 1 = 1

            //10 = 01010,20 = 10100
            byte a = 10;
            byte b = 20;

            Console.WriteLine("Not Equal result example");
            Console.WriteLine("Original " + Environment.NewLine + " A Number: " + a
                + " Binary: " + Convert.ToString(a, 2)
                + Environment.NewLine + " B Number: " + b
                + " Binary: " + Convert.ToString(b, 2));

            long result = a & b;

            Console.WriteLine("Results - Number: " + result
                + " Binary: " + Convert.ToString(result, 2));
    }

OR

סימון ה Operator הוא | , כפי שניתן לראות בדוגמה במקרה שברצף הבתים בערך הראשון יש בתים המוגדרים כ  True - 1  באותו מיקום בערך השני נדרסים הבתים שמוגדים כ False - 0.



 static void exampleOR()
 {
            // 0 on 0 = 0
            // 1 on 0 = 1
            // 0 on 1 = 1
            // 1 on 1 = 1

            //6 = 0110 ,8 = 1000
            byte a = 6;
            byte b = 8;

            Console.WriteLine("Not Equal result example");
            Console.WriteLine("Original " + Environment.NewLine + " A Number: " + a
                + " Binary: " + Convert.ToString(a, 2)
                + Environment.NewLine + " B Number: " + b
                + " Binary: " + Convert.ToString(b, 2));

            long result = a | b;

            Console.WriteLine("Results - Number: " + result
                + " Binary: " + Convert.ToString(result, 2));
}



XOR

סימון ה Operator הוא ^ ,הוא יצור מוזר בסביבת ה Bitwise , ראינו כיצד OR ו AND שינו ערך בשאיפה להגיע ל True או False בעזרת Xor מקבלים קומבינציה חדשה של חיבור בין הערכים, דווקא בתים זהים בערכם ומקומם מתחלפים ל False ואילו ערכים שונים תמיד היו True.




 static void exampleXOR()
 {
            // operator discreption
            //1 on 1 = 0
            //0 on 0 = 0
            //1 on 0 = 1
            //0 on 1 = 1

            byte a = 7;
            //binary equivalent for 7 is 0111

            byte b = 9;
            //binary equivalent for 9 is 1001

            Console.WriteLine("Original " + Environment.NewLine + " A Number: " + a
                + " Binary: " + Convert.ToString(a, 2)
                + Environment.NewLine + " B Number: "+ b
                + " Binary: " + Convert.ToString(b, 2));

            long result = a ^ b;

            Console.WriteLine("Results - Number: " + result
                + " Binary: " + Convert.ToString(result, 2));
    }

דוגמה כיצד לבנות Cipher שהוא קטע קוד שמכיל פונקציות Encryption ו Decryption שמצפינות את המידע בעזרת XOR , המון הצפנות נעזרות ב XOR כחלק מהאולגירתם שהן מריצות, אבל לא ניתן לבסס עליו הצפנה כי היא פשוטה לפריצה.

class Program
{
        //the encryption key
        static string key = "/12Q0Zzy$uo=8GfMc&6Koeqt#e327CBvmJdE%ewRffDX&
                                   #dccDeqEE214&daNdaMzcXds#@42EW
                                   Tfsa99Daryr56337yrrr54RE$$re$32RE54";

        static string message = "this is the encrypted message by bitwise!";
        static void Main(string[] args)
        {
            decryption(encryption(message));
        }

       static string encryption(string msg)
        {
            char[] buffer = msg.ToCharArray();
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = (char)(buffer[i] <<0x3);
                buffer[i] = (char)(buffer[i] ^ key[i % key.Length]);
                buffer[i] = (char)(buffer[i] >> 0x2);
            }

            string o = new string(buffer);
            Console.WriteLine("Encryption String: " + o);
            return o;
        }

        static string decryption(string msg)
        {
            char[] buffer = msg.ToCharArray();

            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = (char)(buffer[i] << 0x2);
                buffer[i] = (char)(buffer[i] ^ key[i % key.Length]);
                buffer[i] = (char)(buffer[i] >> 0x3);

            }

           string o = new string(buffer);
           Console.WriteLine("Decryption String: " + o);
           return o;
        }
 }

NOT

סימון ה Operator הוא ~ , הופך בתים שמוגדים כ False - 0 ל True - 1 ובתים שמוגדים כ True ל False.




static void exampleNOT()
{
            //binary equivalent for 8 is 1000
            byte a = 8;
            Console.WriteLine("Original " + Environment.NewLine + " A Number: " + a
                + " Binary: " + Convert.ToString(a, 2));
         
            //change zero to one and one to zero
            int result = ~a;

            Console.WriteLine("Results - Number: " + result
                + " Binary: " + Convert.ToString(result, 2));
     
}


Bitmask 

מסכה בינארית נפוצה מאוד בעולם ה Embedded, היא מתלבשת על ערך כלשהו ובעזרת AND או OR אנחנו קובעים את חוקיות המסכה, כפי שניתן לראות בדוגמה נניח שיש לנו רכיב עם 8 רגליים וכולם במצב של False בעזרת המסכה ושילוב של OR נדליק את הרגליים ע"פ מבנה המסכה, בדוגמה השניה אפשר לראות שילוב של AND , במקרה שכל הרגליים True בעזרת המסכה נכבה את הרגליים חוץ מהרגליים שמופיעות במסכה.




סיכום:

אז כמו שרואים זה עסק מתסבך ומזל שלא צריכים להתעסק עם זה יותר מידי אבל עדיין חשוב לזכור שזה שם, גם שלא תמיד רואים את זה, בחלק מהמקרים עבודה עם Betwise מהירה יותר מעבודה עם ה Operators רגילים כמו כפל, חילוק, חיבור וחיסור במיוחד בעולם ה Embedded כאשר לא תמיד ניתן לבצע את כל הפעולות.

בהצלחה...


אין תגובות:

הוסף רשומת תגובה