आप शायद अपना पूरा जीवन Rails ऐप्स बनाने में बिता सकते हैं और कभी भी किसी बिटवाइज़ ऑपरेटर का उपयोग करने की आवश्यकता नहीं होगी। यदि आप प्रोग्रामिंग में नए हैं, तो हो सकता है कि आप यह भी न जानते हों कि "बिटवाइज़" का क्या अर्थ है।
लेकिन जिस क्षण आप उन प्रणालियों में रुचि लेते हैं जहां दक्षता महत्वपूर्ण है और संसाधन सीमित हैं, बिटवाइज़ ऑपरेशन महत्वपूर्ण हो जाते हैं। इनका व्यापक रूप से नेटवर्क प्रोटोकॉल, क्रिप्टोग्राफी, यूनिक्स फाइल परमिशन और एम्बेडेड सिस्टम जैसी चीजों के साथ उपयोग किया जाता है।
इसके अलावा, यह समझने के लिए कि कंप्यूटर दो नंबरों को कैसे जोड़ता है जैसी चीजें कैसे करता है, आपको बिटवाइज़ ऑपरेशन को समझना होगा।
चूंकि Ruby और कई अन्य भाषाओं में मूल समर्थन है, वे आपके टूलबॉक्स में जोड़ने के लिए एक बेहतरीन टूल हैं, भले ही यह केवल यह समझने के लिए हो कि भविष्य में यदि आप उनका सामना करते हैं तो क्या हो रहा है।
इस लेख में, हम कवर करेंगे कि बिटवाइज़ ऑपरेशन क्या हैं, कुछ उदाहरण जहां उन्हें लागू किया जा सकता है, और कैसे हम Ruby में उनका सर्वोत्तम उपयोग कर सकते हैं। आइए शुरू करते हैं।
बिटवाइज़ ऑपरेशन क्या हैं?
किसी भी कंप्यूटर में सबसे निचले स्तर पर, हमारे पास केवल 1 और 0 होते हैं, जिन्हें बिट्स के रूप में भी जाना जाता है। Ruby या किसी अन्य प्रोग्रामिंग भाषा में हमारे द्वारा उपयोग किया जाने वाला कोई अन्य ऑपरेशन अंततः 1 और 0 के रूप में संग्रहीत होता है, लेकिन हमारे कंप्यूटर में सॉफ़्टवेयर उन्हें प्रभावी ढंग से आगे और पीछे बदल देता है कि हम क्या देखते हैं और वास्तव में क्या संग्रहीत है। उदाहरण के लिए, हम स्ट्रिंग "hello" को 1 और 0 की एक श्रृंखला के रूप में संग्रहीत करते हैं।
बिटवाइज़ ऑपरेशन हमें सीधे उन बिट्स तक पहुंचने की अनुमति देते हैं, आमतौर पर नंबरों का प्रतिनिधित्व करते हैं, और उनके साथ "कुछ" करते हैं। कुछ ऑपरेशन हमें अपने सॉफ़्टवेयर में सुविधाओं को अधिक सुंदर और कुशल तरीके से लागू करने में मदद करेंगे।
अभी बिटवाइज़ ऑपरेशन के बारे में दो महत्वपूर्ण पहलुओं पर प्रकाश डालना है: वे सूचनाओं को संग्रहीत करने में अत्यधिक प्रभावी हैं, क्योंकि हम सीधे बिट्स का उपयोग कर रहे हैं, और वे निष्पादन में बहुत तेज हैं।
मूल व्यवहार बिट्स का एक सेट होना और उस पर ऑपरेटर लागू करना है। आप दो बिट सेट्स के साथ ऑपरेटर्स का उपयोग भी कर सकते हैं। आइए कुछ ऑपरेशन देखें:
NOT बिटवाइज़ ऑपरेशन
यह एक यूनरी ऑपरेशन है, जिसका अर्थ है कि यह केवल बिट्स के एक सेट पर लागू होता है और यह 1 को 0 से और इसके विपरीत बदलने जितना सरल है। इसे प्रतीक द्वारा दर्शाया जाता है: ~।
~101000 = 010111
AND बिटवाइज़ ऑपरेशन
AND एक ऑपरेशन है जो दो बिट सेट्स पर लागू होता है; इसका प्रतीक & है और यह इस तर्क का पालन करता है:
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
तो जब हमारे पास दो समान-लंबाई वाले बिट सेट होते हैं, तो परिणाम केवल प्रत्येक व्यक्तिगत जोड़ी पर इस तर्क को लागू करना होता है:
0110 AND 0111
-----
0110
Ruby में:
25.to_s(2) # 11001
30.to_s(2) # 11110
(25 & 30).to_s(2) # 11000
OR बिटवाइज़ ऑपरेशन
AND ऑपरेशन के समान, एक और ऑपरेशन जो दो बिट सेट्स पर भी लागू होता है, वह है बिटवाइज़ OR। इसका प्रतीक | है और यह इस तर्क का पालन करता है:
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
तो अगर किसी भी तरफ 1 है, तो परिणाम 1 है, अन्यथा यह 0 है। बहुत सरल! आइए अधिक बिट्स के साथ एक OR ऑपरेशन देखें:
0110 OR 0111
-----
0111
और Ruby में:
25.to_s(2) # 11001
30.to_s(2) # 11110
(25 | 30).to_s(2) # 11111
व्यावहारिक उदाहरण 1: अनुमतियाँ
इस बिंदु पर, आप सोच रहे होंगे कि ये ऑपरेशन उपयोगी क्यों हैं। आखिरकार, वे काफी निम्न-स्तरीय लगते हैं। आपके पास नेटवर्क प्रोटोकॉल, ग्राफिक्स या क्रिप्टोग्राफी के साथ सीधे काम करने की कोई योजना नहीं हो सकती है।
लेकिन आपने शायद पहले परमिशन के साथ काम किया है। परमिशन एक ऐसा क्षेत्र है जहां बिटवाइज़ ऑपरेशन वास्तव में उपयोगी हो सकते हैं। कल्पना करें कि आपके पास एक परमिशन सिस्टम है जहां यूज़र्स डॉक्यूमेंट में अलग-अलग कार्य कर सकते हैं:
- देखें
- संपादित करें
- हटाएं
- अन्य यूज़र्स को आमंत्रित करें
और अब हम इन कार्यों को विभिन्न भूमिकाओं में मॉडल करना चाहते हैं:
- सहायक: डॉक्यूमेंट देख और संपादित कर सकता है।
- पर्यवेक्षक: केवल डॉक्यूमेंट देख सकता है।
- लेखक: सभी कार्य कर सकता है।
हम इसे कैसे मॉडल कर सकते हैं? हम किसी भी बिंदु पर कैसे जानते हैं कि किसी यूज़र के पास इन भूमिकाओं में से एक है? एक उत्तर बिटवाइज़ ऑपरेशन का उपयोग करना है।
हम प्रत्येक यूज़र के लिए केवल एक बिट सेट संग्रहीत करेंगे जो उनके पास मौजूद अनुमतियों का प्रतिनिधित्व करता है:
(दाईं ओर से शुरू)
1st बिट: देखें
2nd बिट: संपादित करें
3rd बिट: हटाएं
4th बिट: अन्य यूज़र्स को आमंत्रित करें
उदाहरण के लिए:
0001 = केवल डॉक्यूमेंट देख सकता है।
0011 = डॉक्यूमेंट देख और संपादित कर सकता है।
1001 = देख सकता है, संपादित नहीं कर सकता, हटा नहीं सकता और दूसरों को आमंत्रित कर सकता है।
एक बार जब हमारे पास कुछ यूज़र्स के लिए ये वैल्यूज़ सेट हो जाते हैं, तो हम जिस परमिशन को चेक करना चाहते हैं, उसके साथ वास्तव में तेज़ तुलना कर सकते हैं। कल्पना करें कि हम चेक कर रहे हैं कि कोई यूज़र डॉक्यूमेंट संपादित कर सकता है या नहीं। हम बिटवाइज़ AND ऑपरेशन का उपयोग कर सकते हैं:
# इसे बिट मास्क कहा जाता है। इसमें केवल वह वैल्यू होती है जिसे हम चेक करना चाहते हैं, इस मामले में संपादन के लिए दूसरा बिट।
EDIT_PERMISSION_MASK = 0b0010
# हम इसे चेक करने के लिए एक त्वरित मेथड परिभाषित कर सकते हैं:
def can_edit_document?(user_permissions)
(EDIT_PERMISSION_MASK & user_permissions) != 0
end
इसका मतलब है कि यदि बिटवाइज़ AND ऑपरेशन हमें 0 से अलग कुछ देता है, तो हमारे पास वह बिट सेट है:
0010 AND 1101
----
0000 == 0 इसलिए हमारे पास परमिशन नहीं है
0010 AND 1110
----
0010 != 0 इसलिए हमारे पास परमिशन है
हम बिट की स्थिति को संशोधित करके किसी भी अन्य परमिशन के लिए समान तर्क लागू कर सकते हैं जिसे हम चेक करना चाहते हैं, इसलिए हम इन स्थिरांक और संबंधित मेथड्स के साथ समाप्त होंगे:
VIEW_PERMISSION_MASK = 0b0001
EDIT_PERMISSION_MASK = 0b0010
DELETE_PERMISSION_MASK = 0b0100
INVITE_PERMISSION_MASK = 0b1000
इसके अलावा, हम एक त्वरित बिट चेक के साथ भविष्य में अनुमतियों को गतिशील रूप से परिभाषित और संग्रहीत कर सकते हैं।
उदाहरण के लिए, हमने पहले कहा था कि एक सहायक केवल डॉक्यूमेंट देख और संपादित कर सकता है, इसलिए उस यूज़र के लिए परमिशन होंगी: 0011। हम उस वैल्यू को अपने डेटाबेस में संग्रहीत कर सकते हैं और फिर पहले से परिभाषित मेथड्स के साथ आसानी से चेक कर सकते हैं कि कोई सहायक कोई कार्य कर सकता है या नहीं।
ASSISTANT_MASK = VIEW_PERMISSION_MASK | EDIT_PERMISSION_MASK # यह होगा: 0011
# वैकल्पिक रूप से, हम इस मेथड का उपयोग यह चेक करने के लिए कर सकते हैं कि यह यूज़र सहायक है या नहीं। यह मेथड User क्लास के अंदर परिभाषित किया जा सकता है।
def is_assistant?(user)
(user.permissions == ASSISTANT_MASK)
end
यदि यह सब परिचित लगता है, तो ऐसा इसलिए है क्योंकि यह यूनिक्स-आधारित सिस्टम में फाइल परमिशन के लिए आमतौर पर उपयोग किए जाने वाले दृष्टिकोण के समान है।
व्यावहारिक उदाहरण 2: टीम में पद
आइए बिटवाइज़ ऑपरेशन का थोड़ा और उपयोग करें 😉।
हम उन्हें एक अन्य मामले में लागू कर सकते हैं जो अपेक्षाकृत आम है: स्पोर्ट्स टीम पर विभिन्न पद या कंपनी में नौकरी के पद। सरल बनाने के लिए बास्केटबॉल टीम के साथ चलते हैं।
बास्केटबॉल में, गेम खेलते समय 5 पोजीशन होती हैं: - पॉइंट गार्ड - शूटिंग गार्ड - स्मॉल फॉरवर्ड - पावर फॉरवर्ड - सेंटर
और हम प्रत्येक पोजीशन को एक बिट सेट असाइन कर सकते हैं: 00001 पॉइंट गार्ड 00010 शूटिंग गार्ड 00100 स्मॉल फॉरवर्ड 01000 पावर फॉरवर्ड 10000 सेंटर
Ruby में वही होगा:
POINT_GUARD_POSITION = 0b00001
SHOOTING_GUARD_POSITION = 0b00010
SMALL_FORWARD_POSITION = 0b00100
POWER_FORWARD_POSITION = 0b01000
CENTER_POSITION = 0b10000
POINT_GUARD_POSITION | SHOOTING_GUARD_POSITION | SMALL_FORWARD_POSITION | POWER_FORWARD_POSITION | CENTER_POSITION
# = 31
तो अब हम कुछ दिलचस्प चीजें कर सकते हैं, जैसे चेक करें कि क्या पूरी टीम मौजूद है:
# p1...p5 प्रत्येक खिलाड़ी की पोजीशन हैं
is_full_team_present = (p1 | p2 | p3 | p4 | p5 == 31)
क्यों? बिटवाइज़ OR ऑपरेशन करके, यदि हमारे पास सभी पोजीशन थीं, तो हम अंत में प्राप्त करेंगे: 11111।
# OR बिटवाइज़ ऑपरेशन
00001 | 00010 | 00100 | 01000 | 10000
-----
11111
और 11111, 31 है, क्योंकि 2^0 + 2^1 + 2^2 + 2^3 + 2^4 = 31।
यह बिटवाइज़ ऑपरेशन से सख्ती से संबंधित नहीं है, लेकिन इस डेटा मॉडलिंग के साथ हम यह भी चेक कर सकते हैं कि दो खिलाड़ियों का आदान-प्रदान किया जा सकता है या नहीं। यह बहुत सरल होगा:
def can_be_exchanged?(player1, player2)
player1.position == player2.position
end
XOR
एक और ऑपरेशन जो हम दो बिट सेट्स के साथ कर सकते हैं वह है XOR, जिसका प्रतीक ^ है।
XOR का अर्थ है एक्सक्लूसिव OR और यह इस तर्क का पालन करता है:
1 | 1 = 0
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
तो परिणाम केवल तभी 1 होगा जब दो बिट्स में से एक 1 हो; यदि दोनों बराबर हैं तो यह 0 होगा।
इस ऑपरेशन का उपयोग कुछ एल्गोरिदम में एक संख्या की तुलना स्वयं से करने के लिए किया जाता है, क्योंकि x ^ x = 0।
शिफ्ट्स
यह ऑपरेशन का एक दिलचस्प समूह है जहां हम एक सेट के भीतर बिट्स को एक तरफ या दूसरी तरफ "स्थानांतरित" करते हैं। मुझे समझाने दें।
बिट शिफ्ट के साथ, हम बिट्स को एक दिशा में, बाएं या दाएं "स्थानांतरित" या "शिफ्ट" करते हैं:
00010111 left-shift <-------
00101110
10010111 right-shift ------->
11001011
हम बिट्स को n बार स्थानांतरित या शिफ्ट कर सकते हैं। यहाँ Ruby में संख्या 5 पर दो बार लागू लेफ्ट शिफ्ट है:
5.to_s(2) # 101
(5 << 2).to_s(2) # 10100
जैसा कि आप देख सकते हैं, एक लेफ्ट शिफ्ट को << द्वारा दर्शाया जाता है। एक राइट शिफ्ट >> का उपयोग करता है:
5.to_s(2) # 101
(5 >> 2).to_s(2) # 1
इस मामले में, हमें केवल एक मिलता है, क्योंकि 1*01* से बिट्स "0" और "1" को त्याग दिया गया है।
राइट शिफ्ट से 2 से भाग दें
बिट शिफ्ट के बारे में एक दिलचस्प तथ्य यह है कि आप उनके साथ कुछ गणितीय ऑपरेशन की गणना कर सकते हैं। अतीत में, यह तेज़ था, लेकिन आजकल यह लगभग विशेष रूप से उन प्रोग्रामर्स द्वारा उपयोग किया जाता है जो गेम डेवलपमेंट जैसे संसाधनों में अधिक बाधाओं के साथ काम करते हैं।
यदि हम किसी संख्या पर राइट शिफ्ट लागू करते हैं, तो हमें इसे 2 से विभाजित करने का परिणाम मिलता है:
10.to_s(2) # 1010
(10 >> 1).to_s(2) # 101
10 >> 1 # 5
लेफ्ट शिफ्ट से 2 से गुणा करें
उसी तरह, हम लेफ्ट शिफ्ट के साथ 2 से गुणा कर सकते हैं:
10.to_s(2) # 1010
(10 << 1).to_s(2) # 10100
10 << 1 # 20
जल्दी जांचें क्या संख्या विषम या सम है
बिटवाइज़ ऑपरेशन का एक बहुत सरल उदाहरण है जो वास्तव में तेज़ और पालन करने में आसान है।
कल्पना करें कि हम 1 के साथ AND ऑपरेशन करते हैं, बस 1। तो वह कंप्यूटर के आधार पर किसी भी संख्या में 0 होंगे, और 1। आइए इसे 2 के साथ करें:
2 = 00000010
& 00000001
-------------
00000000
अब 4 के साथ:
4 = 00000100
& 00000001
-------------
00000000
5 के बारे में क्या?
5 = 00000101
& 00000001
-------------
00000001
अब हमें 1 मिला। क्या आप अनुमान लगा सकते हैं कि इसका क्या अर्थ है?
1 के साथ यह AND करके, यदि संख्या सम है, तो हमें 0 मिलेगा। यदि यह विषम है, तो हमें 1 मिलेगा। हम इस तथ्य का उपयोग Ruby में कुछ मेथड्स बनाने के लिए आसानी से कर सकते हैं:
def is_odd?(number)
number & 1
end
def is_even?(number)
is_odd?(number) == 0
end
# या:
def is_even?(number)
(number & 1) == 0
end
यदि आप आगे जाना चाहते हैं, या बिट्स के साथ कुछ दिमाग उड़ाने वाले क्षणों का अनुभव करना चाहते हैं, तो अधिक ट्रिक्स के लिए इस बिटवाइज़ हैक्स संग्रह को देखें।
निष्कर्ष
बिटवाइज़ ऑपरेशन का पालन करना कठिन है यदि आपने कभी उनका सामना नहीं किया है, लेकिन एक बार जब आप उनसे परिचित हो जाते हैं तो आप मौजूदा या भविष्य की परियोजनाओं से निपटने के लिए बेहतर तैयार होंगे जो उनका उपयोग करते हैं। साथ ही, आपके कोड में किसी समस्या के समाधान की योजना बनाते समय आपके पास एक नया टूल होगा।