Presentation is loading. Please wait.

Presentation is loading. Please wait.

סיביות קרן כליף. © Keren Kalif 2 ביחידה זו נלמד:  מוטיבציה  אופרטורים לעבודה עם סיביות:  &  |  ^  ~  >>  <<

Similar presentations


Presentation on theme: "סיביות קרן כליף. © Keren Kalif 2 ביחידה זו נלמד:  מוטיבציה  אופרטורים לעבודה עם סיביות:  &  |  ^  ~  >>  <<"— Presentation transcript:

1 סיביות קרן כליף

2 © Keren Kalif 2 ביחידה זו נלמד:  מוטיבציה  אופרטורים לעבודה עם סיביות:  &  |  ^  ~  >>  <<

3 © Keren Kalif 3 מוטיבציה  כל משתנה בזכרון מיוצג ע"י כמה תאים, ובפרט ע"י אוסף של סיביות  עד היום עבדנו עם משתנים, ללא יכולת לפנות לסיביות המרכיבות אותם  מוטיבציה:  דחיסה: אם רוצים לשמור טקסט באנגלית, יספיקו לנו רק כ- 30 תווים: האותיות וסימני הפיסוק. בפועל עבור כל תו נשמור 8 סיביות (255 קומבינציות). ע"י דחיסה נוכל לשמור עבור כל תו רק 5 סיביות. חסכון של כ- 35%!  הצפנה: ניתן להחליט על החלפה כלשהי בסדר הסיביות, שתהייה ידועה רק לנו או למי שאמור לפענח את המידע

4 © Keren Kalif 4 פעולות על סיביות  נסתכל על התוכנית הבאה, וכיצד יראה ה- byte שיכיל את הנתון: void main() { char ch = ‘a'; {  פעולות שניתן לבצע עם סיביות:  &  AND  |  OR  ^  XOR  ~  NOT  >> Left Shift  << Rigtt Shift  פעולות על סיביות ניתן לבצע על משתנים מטיפוסים המכילים שלמים בלבד (char, int, short, long) 0 1 1 0 0 0 0 1

5 © Keren Kalif 5 הפעולה & (AND) 1. void printCharAsBinary(char ch) {…} 2. 3. void main() 4. { 5. char ch1 = 'a', ch2 = 'b', ch3 = ch1&ch2; 6. 7. printf("ch1=%c: ", ch1); 8. printCharAsBinary(ch1); 9. 10. printf("\nch2=%c: ", ch2); 11. printCharAsBinary(ch2); 12. 13. printf("\nch3=%c: ", ch3); 14. printCharAsBinary(ch3); 15. printf("\n"); 16. } הפעולה & בין שני משתנים עושה את הפעולה & על כל זוג סיביות במשתנים. אם שניהם 1, גם התוצאה תהיה 1, אחרת 0.  & עם 0 "מכבה" ביט מסוים  & עם 1 משאיר את הביט ללא שינוי

6 © Keren Kalif 6 הפעולה | (OR) 1. void printCharAsBinary(char ch) {…} 2. 3. void main() 4. { 5. char ch1 = 'a', ch2 = 'b', ch3 = ch1|ch2; 6. 7. printf("ch1=%c: ", ch1); 8. printCharAsBinary(ch1); 9. 10. printf("\nch2=%c: ", ch2); 11. printCharAsBinary(ch2); 12. 13. printf("\nch3=%c: ", ch3); 14. printCharAsBinary(ch3); 15. printf("\n"); 16. } הפעולה | בין שני משתנים עושה את הפעולה | על כל זוג סיביות במשתנים. אם לפחות אחד מהם 1, גם התוצאה תהיה 1, אחרת 0.  | עם 1 "מדליק" ביט מסוים  | עם 0 משאיר את הביט ללא שינוי

7 © Keren Kalif 7 הפעולה ^ (XOR) 1. void printCharAsBinary(char ch) {…} 2. 3. void main() 4. { 5. char ch1 = 'a', ch2 = 'b', ch3 = ch1^ch2; 6. 7. printf("ch1=%c: ", ch1); 8. printCharAsBinary(ch1); 9. 10. printf("\nch2=%c: ", ch2); 11. printCharAsBinary(ch2); 12. 13. printf("\nch3=%c: ", ch3); 14. printCharAsBinary(ch3); 15. printf("\n"); 16. } הפעולה ^ בין שני משתנים עושה את הפעולה ^ על כל זוג סיביות במשתנים. אם בדיוק אחד מהם 1, גם התוצאה תהיה 1, אחרת 0.  ^ עם 1 הופך את הביט  ^ עם 0 משאיר את הביט ללא שינוי  ^ עם עצמו מאפס את המשתנה

8 © Keren Kalif 8 הפעולה >> (Shift Left) 1. void printCharAsBinary(char ch) {…} 2. 3. void main() 4. { 5. char ch1 = 'a', ch2 = ch1 << 1; 6. 7. printf("ch1=%c: ", ch1); 8. printCharAsBinary(ch1); 9. 10. printf("\nch2=%c: ", ch2); 11. printCharAsBinary(ch2); 12. 13. printf("\n"); 14. } הפעולה >> מזיזה את הסיביות במשתנה n פעמים שמאלה, ומוסיפה n אפסים מימין

9 © Keren Kalif 9 הפעולה << (Shift Right) על משתנים שהם signed 1. void printCharAsBinary(char ch) {…} 2. void main() 3. { 4. char ch1 = 'a', ch2 = ch1 >> 1; 5. char ch3 = 128, ch4 = ch3 >> 2; 6. 7. printf("ch1=%c: ", ch1); 8. printCharAsBinary(ch1); 9. 10. printf("\nch2=%c: ", ch2); 11. printCharAsBinary(ch2); 12. 13. printf("\nch3=%c: ", ch3); 14. printCharAsBinary(ch3); 15. 16. printf("\nch4=%c: ", ch4); 17. printCharAsBinary(ch4); 18. printf("\n"); 19. } הפעולה << מזיזה את הסיביות במשתנה n פעמים ימינה, ומוסיפה n פעמים את הביט הכי שמאלי (כאשר המשתנה signed)

10 © Keren Kalif 10 הפעולה << (Shift Right) על משתנים שהם unsigned 1. void printCharAsBinary(char ch) {…} 2. void main() 3. { 4. char ch1 = 'a', ch2 = ch1 >> 1; 5. unsigned char ch3 = 128, ch4 = ch3 >> 2; 6. 7. printf("ch1=%c: ", ch1); 8. printCharAsBinary(ch1); 9. 10. printf("\nch2=%c: ", ch2); 11. printCharAsBinary(ch2); 12. 13. printf("\nch3=%c: ", ch3); 14. printCharAsBinary(ch3); 15. 16. printf("\nch4=%c: ", ch4); 17. printCharAsBinary(ch4); 18. printf("\n"); 19. } הפעולה << מזיזה את הסיביות במשתנה n פעמים ימינה, ומוסיפה n פעמים 0'ים מימין (כאשר המשתנה unsigned)

11 © Keren Kalif 11 שימושים לפעולות בסיסיות עם סיביות  הכפלת מספר פי 2: shift left פעם אחת  חילוק מספר פי 2: shift rightפעם אחת void main() } char num1 = 17, num2 = num1 > 1; printf("num1 in binary: "); printCharAsBinary(num1); printf(“\nnum2 in binary: "); printCharAsBinary(num2); printf(“\nnum3 in binary: "); printCharAsBinary(num3); printf(“\nnum1=%d, num2=%d, num3=%d\n", num1, num2, num3); {

12 © Keren Kalif 12 void printCharAsBinary(char ch) { int i; unsigned char temp; for ( ; ; ) } temp = ch << i; temp = temp >> 7; printf("%d", temp); { { 0 1 1 0 0 0 0 1 מימוש הפונקציה printCharAsBinary בכל איטרציה מבודדים את הביט ה- i שמשמאל i=0i < 8i++ ch = ‘a’  97 0 1 1 0 0 0 0 1 temp 0 0 0 0 0 0 0 0 i = 0 printed to screen: 0 i = 1 1 1 0 0 0 0 1 00 0 0 0 0 0 0 1 1 i = 2 1 0 0 0 0 1 0 00 0 0 0 0 0 0 1 1 i = 3 0 0 0 0 1 0 0 0 0 0 0 0 0

13 © Keren Kalif 13 קבלת הביט במיקום ה- i (משמאל) 1. int getBitFromLeft(unsigned char ch, int index) 2. { 3. unsigned char temp = ch << index; 4. temp >>= 7; 5. return temp; 6. { 7. 8. void main() 9. } 10. char ch1 = 'a'; 11. int i; 12. 13. printf("ch1=%c: ", ch1); 14. printCharAsBinary(ch1); 15. 16. printf("\n"); 17. for (i=0 ; i < 8 ; i++) 18. printf("the %d bit: %d\n", i, getBitFromLeft(ch1, i)); 19. { ch = ‘a’  97 0 1 1 0 0 0 0 1 temp 1 0 0 0 0 1 0 0 index = 2 0 0 0 0 0 0 0 1

14 © Keren Kalif 14 קבלת הביט במיקום ה- i (מימין) בעזרת מסיכה int getBitFromRight(unsigned char ch, int index) { unsigned char mask = 1; // 00000001 mask = mask << index; if (ch & mask == 0) return 0; else return 1; { ch = ‘a’  97 0 1 1 0 0 0 0 1 mask index = 5 0 0 0 0 0 0 0 10 0 1 0 0 0 0 0

15 © Keren Kalif 15 השמת ערך בביט ה- i (מימין) char setBitFromRight(unsigned char ch, int index, int value) { unsigned char mask = 1; // 00000001 unsigned char result; mask <<= index; if (value == 1) result = ch | mask; else } mask = ~mask; result = ch & mask; { return result ; { ch = ‘a’  97 0 1 1 0 0 0 0 1 mask index = 5 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 value = 0 0 0 1 0 0 0 0 01 1 0 1 1 1 1 1 result

16 © Keren Kalif 16 השמת ערך בביט ה- i (מימין) char setBitFromRight(unsigned char ch, int index, int value) { unsigned char mask = 1; // 00000001 unsigned char result; mask <<= index; if (value == 1) result = ch | mask; else } mask = ~mask; result = ch & mask; { return result ; { ch = ‘a’  97 0 1 1 0 0 0 0 1 mask index = 4 0 0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 value = 1 0 0 0 1 0 0 0 0 result

17 © Keren Kalif 17 מימוש הפונקציה swap void swap(int* x, int* y) } *x = *x ^ *y; *y = *x ^ *y; *x = *x ^ *y; { void main() } int x = 3, y = 5; printf("Before swap: x=%d, y=%d\n", x, y); swap(&x, &y); printf("After swap: x=%d, y=%d\n", x, y); { x 0 0 0 0 0 0 1 1 y 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1

18 © Keren Kalif 18 הוכחה לפונקציה swap void swap(int* x, int* y) } *x = *x ^ *y; *y = *x ^ *y; *x = *x ^ *y; { הערך החדשהפעולההמשתנה המקורי YXYX YX ^ YX = X ^ YYX Y = (X ^ Y) ^ Y = X ^ (Y ^ Y) = X ^ 0 = X X ^ YY = X ^ YYX ^ Y XX = (X ^ Y)s ^ X) = Y ^ X ^ X = Y ^ 0 = Y X = X ^ YXX ^ Y

19 © Keren Kalif 19 מימוש גנרי לפונקציה swap 1. void swap(void* a, void* b, int typeSize) 2. { 3. int i; 4. char* first = (char*)a; 5. char* second = (char*)b; 6. for (i=0 ; i < typeSize ; i++) 7. } 8. *(first+i) = *(first+i) ^ *(second+i); 9. *(second+i) = *(first+i) ^ *(second+i); 10. *(first+i) = *(first+i) ^ *(second+i); 11. { 12. { 13. void main() 14. } 15. int x = 331, y = 54295; 16. char str1[4]="hi", str2[4]="bye"; 17. 18. printf("Before: x=%d, y=%d\n", x, y); 19. swap(&x, &y, sizeof(int)); 20. printf("After: x=%d, y=%d\n", x, y); 21. printf("\nBefore: str1=%s, str2=%s\n", str1, str2); 22. swap(str1, str2, sizeof(str1)); 23. printf(“After: str1=%s, str2=%s\n", str1, str2); 24. {

20 © Keren Kalif 20 דוגמא פשוטה להצפנת ופיענוח טקסט 1. void encryptDecrypt(char str[]) 2. { 3. while (*str != '\0') 4. } 5. *str ^= 255; 6. str++; 7. { 8. { 9. 10. void main() 11. } 12. char str[] = "ma katoov po?"; 13. 14. printf("Text before encryption: |%s|\n", str); 15. encryptDecrypt(str); 16. printf("Text after encryption: |%s|\n", str); 17. encryptDecrypt(str); 18. printf("Text after decryption: |%s|\n", str); 19. { תזכורת: XOR עם 1 הופכת את סיביות המשתנה

21 © Keren Kalif 21 דוגמא  כתוב פונקציה המקבלת שם של קובץ בינארי וכמות כלשהי של מספרים, שנתון שסכומם הוא 8 (המספר האחרון יהיה 0, ליצוג סיום הפרמטרים)  כל מספר מייצג כמות סיביות המייצגות מספר.  יש לקרוא את הקובץ הבינארי ולהציג את המספרים המקודדים בתוכו.  למשל, עבור המספרים 4,1,3 והבתים הבאים שנקראו מהזכרון (abc): 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 יודפסו למסך המספרים הבאים:

22 © Keren Kalif 22 זכרו! http://funny-stuff.audio4fun.com/download/funnypixstore/10796.jpg

23 © Keren Kalif 23 1. #include 2. #include 3. #include 4. #include 5. 6. unsigned char createMask(int high, int low); 7. int getSubNumber(char ch, unsigned char mask, int high, int low); 8. void readNumbers(const char* fileName,...); 9. 10. void main() 11. { 12. char str[] = "abc"; // a: 01100001 b: 01100010 c: 01100011 13. FILE* f = fopen("test.bin", "wb"); 14. fwrite(str, sizeof(char), strlen(str), f); 15. fclose(f); 16. 17. readNumbers("test.bin", 4, 1, 3, 0); 18. {

24 © Keren Kalif /* This function receives higher and lower bounds of bit indexes, and creates a mask with 1 in this range, and 0 in all other places. I.E: high=5, low=3, the mask char would be: 00111000 */ 19. unsigned char createMask(int high, int low) 20. { 21. return ( 1 << ( high + 1 ) ) - ( 1 << low ); 22. { © Keren Kalif 24 6 >> 1 1000000 64 3 >> 1 1000 8 56=64-8 00111000 מוזמנים לקרוא את ההסבר לפונקציה זו בדפים שבאתר!

25 © Keren Kalif 25 28. void readNumbers(const char* fileName,...) 29. { 30. FILE* f; 31. va_list numbers; 32. int highBit, lowBit, i, numOfNumbers=0, arr[8]; 33. unsigned char ch; 34. unsigned char* masks; 35. 36. f = fopen(fileName, "rb"); 37. if (f == NULL) 38. exit(1); 39. 40. // get the numbers 41. va_start(numbers, fileName); 42. arr[numOfNumbers] = va_arg(numbers, int); 43. while (arr[numOfNumbers] != 0) 44. } 45. numOfNumbers++; 46. arr[numOfNumbers] = va_arg(numbers, int); 47. { 48. 49. // allocate the masks array 50. masks = (char*)malloc(numOfNumbers*sizeof(unsigned char));

26 © Keren Kalif 26 51. // creates the masks 52. highBit=7; 53. for (i=0 ; i < numOfNumbers ; i++) 54. } 55. lowBit = highBit - arr[i] + 1; 56. masks[i] = createMask(highBit, lowBit); 57. highBit = lowBit - 1; 58. } 59. while (1) 60. } 61. fread(&ch, sizeof(char), 1, f); 62. if (feof(f))break; 63. printf("From char '%c' --> ", ch); 64. highBit=7; 65. for (i=0 ; i < numOfNumbers ; i++) 66. { 67. lowBit = highBit - arr[i] + 1; 68. printf("%d ", ((ch & masks[i]) >> lowBit)); 69. highBit = lowBit - 1; 70. } 71. printf("\n"); 72. { 73. fclose(f); 74. free(masks); 75. {

27 © Keren Kalif 27 דוגמא 1: יצירת קובץ בינארי המכיל קידוד תמונה  יש לייצר קובץ בינארי המכיל יצוג של תמונה.  תמונה מורכבת מ- M*N פיקסלים, כך שלכל פיקסל יש צבע (יש 16 צבעים אפשריים).  יש לכתוב לקובץ את מימדי התמונה ואח"כ את כל הפיקסלים לפי הסדר: הפיקסלים מהשורה הראשונה, השניה וכו'.  על מנת לשמור כל צבע, ניתן להסתפק ב- 4 סיביות  בכל byte ניתן לשמור נתונים עבור 2 פיקסלים  תמונה עם M*N פיקסלים תשמר ב- N*M/2 + 2 בתים 2 בתים בהתחלה לשמירת מימדי התמונה

28 © Keren Kalif 28 דוגמא 2: שינוי צבע לפיקסל מסוים בתמונה  יש לתת קאורדינטת x,y וצבע, ובגישה ישירה לעדכן את הפיקסל.  יש לשים לב האם הצבע עבור הקאורדינטה המבוקשת נמצא בצד הימני אא בצד השמאלי של ה- byte בו הוא נשמר

29 © Keren Kalif 29 ביחידה זו למדנו:  מוטיבציה  אופרטורים לעבודה עם סיביות:  &  |  ^  ~  >>  <<

30 © Keren Kalif 30 תרגיל


Download ppt "סיביות קרן כליף. © Keren Kalif 2 ביחידה זו נלמד:  מוטיבציה  אופרטורים לעבודה עם סיביות:  &  |  ^  ~  >>  <<"

Similar presentations


Ads by Google