פעולות Bitwise ב- VB.NET

VB.NET אינו תומך ישירות בפעולות ברמת הסיביות. Framework 1.1 (VB.NET 2003) הציג מפעילי shift bit (<< ו >>), אך אין דרך למטרה כללית לתמרן חלקים בודדים. פעולות ביט פחית להיות שימושי מאוד. לדוגמה, ייתכן שהתוכנית שלך תצטרך להתממשק עם מערכת אחרת הדורשת מניפולציה של סיביות. אבל בנוסף, יש המון טריקים שניתן לעשות באמצעות ביטים בודדים. מאמר זה סוקר מה ניתן לעשות עם מניפולציות באמצעות VB.NET.

אתה צריך להבין מפעילים קצת לפני הכל. ב- VB.NET, אלה הם:

  • ו
  • או
  • קסור
  • לא

ביטוולי פשוט אומר שניתן לבצע את הפעולות על שני מספרים בינאריים טיפין. מיקרוסופט משתמשת טבלאות אמת לתיעוד פעולות חריגות. שולחן האמת ל ו הוא:

תוצאה של Bit Bit 2
1 1 1
1 0 0
0 1 0
0 0 0

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


לחץ כאן כדי להציג את האיור
לחץ על כפתור הקודם בדפדפן כדי לחזור

להלן דוגמא פשוטה באמצעות ו פעולה עם מספרים בינאריים של שני, ארבעה ביט:

התוצאה של 1100 ו 1010 הוא 1000.

זה בגלל 1 ו 1 הוא 1 (הקטע הראשון) והשאר 0.

ראשית, נסתכל על פעולות הסיביות ש הם נתמך ישירות ב- VB.NET: קצת משתנה. אמנם קיימים גם משמרת שמאלה וגם משמרת ימינה, אך הם עובדים באותה צורה כך שרק משמרת שמאל תידון. הסטת סיביות משמשת לרוב בקריפטוגרפיה, עיבוד תמונה ותקשורת.

instagram viewer

פעולות הסטה של ​​VB.NET ...

  • עבוד רק עם ארבעת סוגי המספרים השלמים: בייט, קצר, מספר שלם, ו ארוך
  • הם חשבון פעולות הסטה. המשמעות היא שפיסות שהועברו לסוף התוצאה נזרקות, ומיקומי הסיביות שנפתחו בקצה השני מוגדרים לאפס. האלטרנטיבה נקראת הסטת סיביות מעגליות והקטעים המועברים בקצה האחד פשוט מתווספים לקצה השני. VB.NET אינו תומך בהחלפת סיביות מעגליות ישירות. אם אתה זקוק לזה, תצטרך לתקן את זה בצורה המיושנת: להכפיל או לחלק ב -2.
  • לעולם אל תייצר חריגה של הצפת יתר. VB.NET דואג לכל בעיה אפשרית ואני אראה לך מה זה אומר. כאמור, אתה יכול לקוד את הסטת הסיביות שלך על ידי הכפלה או חלוקה ב- 2, אך אם אתה משתמש ב- גישת "קוד משלך", עליך לבדוק חריגות של הצפות יתר שיכולות לגרום לתוכנית שלך התרסקות.

פעולת הסטת סיביות סטנדרטית תיראה כך:

ערך התחלתי עמום כמספר שלם = 14913080
הערך העמום משמרת כמספר שלם
ValueAfterShifting = ערך ערך << 50

במילים, פעולה זו גוברת את הערך הבינארי 0000 0000 1110 0011 1000 1110 0011 1000 (14913080 הוא הערך העשרוני המקביל - שימו לב שזו רק סדרה של 3 0 ושל 3 1 שחוזרים עליה כמה פעמים) ומסירה אותה 50 מקומות שנותרו. אך מכיוון שמספר שלם באורך של 32 סיביות בלבד, אין צורך להחליף אותו 50 מקומות. VB.NET פותר את הבעיה על ידי מיסוך ספירת המשמרות עם ערך סטנדרטי התואם את סוג הנתונים המשמש. במקרה הזה, ValueAfterShifting הוא מספר שלם כך שהמקסימום שניתן להסיט הוא 32 סיביות. ערך המסכה הסטנדרטי שעובד הוא 31 עשרוניים או 11111.

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

בעשרוני:

50 ו -31 הוא 18 - המספר המרבי של ביטים שניתן להזיז

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

110010 ו 11111 הוא 10010

כאשר מבצע קטע הקוד, התוצאה היא 954204160 או, בינארית, 0011 1000 1110 0000 0000 0000 0000 0000. 18 הסיביות בצד שמאל של המספר הבינארי הראשון מופנות ו -14 הסיביות בצד ימין מועברות שמאלה.

הבעיה הגדולה השנייה עם העברת חלקים היא מה שקורה כשמספר המקומות לתזוזה הוא מספר שלילי. בואו להשתמש ב- -50 כמספר הסיביות כדי לעבור ולראות מה קורה.

ValueAfterShifting = ערך ערך << -50

כאשר קטע קוד זה מופעל, אנו מקבלים -477233152 או 1110 0011 1000 1110 0000 0000 0000 0000 בבינארי. המספר הועבר 14 מקומות שנותרו. למה 14? VB.NET מניח שמספר המקומות הוא מספר שלם שלא חתום ועושה ו פעולה עם אותה מסכה (31 עבור מספרים שלמים).

1111 1111 1111 1111 1111 1111 1100 1110
0000 0000 0000 0000 0000 0000 0001 1111
(וגם)
0000 0000 0000 0000 0000 0000 0000 1110

1110 בינארית הוא 14 עשרוני. שימו לב שזה הפוך ממעבר 50 חיובי.

בעמוד הבא, אנו עוברים לכמה פעולות ביט אחרות, החל מ הצפנת Xor!

ציינתי כי שימוש אחד בפעולות ביט הוא הצפנה. הצפנת Xor היא דרך פופולרית ופשוטה "להצפין" קובץ. במאמר שלי, Encryption Very Simple באמצעות VB.NET, אני מראה לך דרך טובה יותר להשתמש במניפולציה של מחרוזות במקום. אבל הצפנת Xor כל כך נפוצה שהיא ראויה לפחות להסביר אותה.

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

הצפנת Xor נקראת "אלגוריתם סימטרי". משמעות הדבר היא שאנחנו יכולים להשתמש במפתח ההצפנה גם כמפתח הפענוח.

בואו להשתמש ב- "A" כמפתח ונצפין את המילה "Basic". קוד ASCII עבור "A" הוא:

0100 0001 (65 עשרונית)

קוד ASCII עבור Basic הוא:

B - 0100 0010
א - 0110 0001
s - 0111 0011
i - 0110 1001
ג - 0110 0011

ה קסור מכל אחד מאלה הוא:

0000 0011 - 3 עשרוני
0010 0000 - 32 עשרונית
0011 0010 - 50 עשרוניים
0010 1000 - 40 עשרוניים
0010 0010 - 34 עשרוניים

השגרה הקטנה הזו עושה את העבודה:

- הצפנת Xor -
Dim i כמו קצר
ResultString. טקסט = ""
עמעום KeyChar כמספר שלם
KeyChar = Asc (EncryptionKey. טקסט)
עבור i = 1 לן (InputString. טקסט)
ResultString. טקסט & = _
Chr (KeyChar Xor _
Asc (אמצע (InputString. טקסט, אני, 1)))
הבא

ניתן לראות את התוצאה באיור זה:


לחץ כאן כדי להציג את האיור
לחץ על כפתור הקודם בדפדפן כדי לחזור

כדי להפוך את ההצפנה, פשוט העתק והדבק את המחרוזת מ- TextBox התוצאה בחזרה לתוך TextBox המחרוזת ולחץ על הכפתור שוב.

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

אפלולי ראשונה כמספר שלם
אפלולי את השני כמספר שלם
FirstInt = CInt (FirstIntBox. טקסט)
SecondInt = CInt (SecondIntBox. טקסט)
FirstInt = FirstInt Xor SecondInt
SecondInt = FirstInt Xor SecondInt
FirstInt = FirstInt Xor SecondInt
תיבת התיבה. טקסט = "מספר שלם ראשון:" & _
FirstInt. ToString & "-" & _
"מספר שלם שני:" & _
SecondInt. ToString

והנה הקוד בפעולה:


לחץ כאן כדי להציג את האיור
לחץ על כפתור הקודם בדפדפן כדי לחזור

להבין בדיוק מדוע זה עובד יישאר "כתרגיל לתלמיד".

בעמוד הבא אנו מגיעים למטרה: מניפולציה כללית של סיביות

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

אולי הסיבה שהיא חסרה היא שזה לא כל כך קשה לכתוב תתי-משנה שמשיגים את אותו הדבר.

סיבה טיפוסית לכך שאולי תרצו לעשות זאת היא לשמור על מה שמכונה לעיתים א דגל בתים. יישומים מסוימים, במיוחד כאלה שנכתבים בשפות ברמה נמוכה כמו הרכבה, ישמרו על שמונה דגלים בוליאניים בבת אחת. לדוגמה, מרשם הסטטוסים של שבב מעבד 6502 מכיל מידע זה בבתים בודדים של 8 ביט:

ביט 7. דגל שלילי
ביט 6. דגל הצפת
ביט 5. לא בשימוש
ביט 4. לשבור דגל
ביט 3. דגל עשרוני
ביט 2. הפסק את השבת הדגל
ביט 1. דגל אפס
ביט 0. נשא דגל

(מתוך ויקיפדיה)

אם הקוד שלך צריך לעבוד עם נתונים מסוג זה, אתה זקוק לקוד מניפולציה סיבית לכל מטרה. קוד זה יעשה את העבודה!

'ה- ClearBit Sub מנקה את הסיבוב הראשון מבוסס ה- 1
'(MyBit) של מספר שלם (MyByte).
תת ClearBit (ByRef MyByte, ByVal MyBit)
מסיכת BitMask כמו Int16
'צור מסיכת סיביות עם ערכת הסיביות השנייה עד ה- n:
BitMask = 2 ^ (MyBit - 1)
'נקה את הסיבית התשיעית:
MyByte = MyByte ולא BitMask
סיום משנה
'הפונקציה ExamineBit תחזיר נכון או לא נכון
'תלוי בערך של הסיבית הראשונה המבוססת על ה- 1 (MyBit)
של מספר שלם (MyByte).
פונקציה ExamineBit (ByVal MyByte, ByVal MyBit) כמו בוליאני
מסיכת BitMask כמו Int16
BitMask = 2 ^ (MyBit - 1)
ExamineBit = ((MyByte ו- BitMask)> 0)
פונקצית סיום
תת המשנה SetBit יגדיר את הסיבית ה- 1 המבוססת על 1
'(MyBit) של מספר שלם (MyByte).
Sub SetBit (ByRef MyByte, ByVal MyBit)
מסיכת BitMask כמו Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte או BitMask
סיום משנה
'תת ToggleBit ישנה את המצב
'מהסיבית 1 המבוססת על ה- 1 (MyBit)
של מספר שלם (MyByte).
Sub ToggleBit (ByRef MyByte, ByVal MyBit)
מסיכת BitMask כמו Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte Xor BitMask
סיום משנה

כדי להדגים את הקוד, שיגרה זו מכנה זאת (פרמטרים שלא מקודדים ב- Sub לחץ):

תת פרטי ExBitCode_Click (...
Dim Byte1, Byte2 As Byte
עמום MyByte, MyBit
מצב עמום כמו Boolean
עמום נבחר RB כמחרוזת
סטטוס ליין. טקסט = ""
SelectedRB = GetCheckedRadioButton (אני) .Name
Byte1 = ByteNum. טקסט 'מספר להמרה לדגלי ביט
Byte2 = BitNum. טקסט 'קצת שיש להחליף
להלן מנקה את בתים בסדר גודל גבוה ומחזיר רק את ה-
בתים לפי סדר נמוך:
MyByte = Byte1 ו- HFF
MyBit = Byte2
בחר מקרה שנבחר RB
התיק "ClearBitButton"
ClearBit (MyByte, MyBit)
סטטוס ליין. טקסט = "בייט חדש:" ו- MyByte
המקרה "ExamineBitButton"
StatusOfBit = ExamineBit (MyByte, MyBit)
סטטוס ליין. טקסט = "קצת" ו- MyBit & _
"הוא" & StatusOfBit
התיק "SetBitButton"
SetBit (MyByte, MyBit)
סטטוס ליין. טקסט = "בייט חדש:" ו- MyByte
התיק "ToggleBitButton"
ToggleBit (MyByte, MyBit)
סטטוס ליין. טקסט = "בייט חדש:" ו- MyByte
סיום בחירה
סיום משנה
פונקציה פרטית GetCheckedRadioButton (_
הורית ByVal כבקרה) _
כ- RadioButton
Dim FormControl כבקרה
עמעום RB כ- RadioButton
עבור כל FormControl בהורה. בקרות
אם FormControl. GetType () האם GetType (RadioButton) ואז
RB = DirectCast (FormControl, RadioButton)
אם RB בדוק ואז החזר RB
סוף אם
הבא
לא להחזיר דבר
פונקצית סיום

הקוד בפעולה נראה כך:


לחץ כאן כדי להציג את האיור
לחץ על כפתור הקודם בדפדפן כדי לחזור

instagram story viewer