top

Search

Python Tutorial

.

UpGrad

Python Tutorial

XOR in Python

Introduction

In this tutorial, we delve into the concept of XOR in Python. Recognized as 'Exclusive OR', XOR is not just a logical operation; it’s a cornerstone of advanced programming and data handling in Python. Its applications span from encryption to error detection, positioning it as an indispensable tool. As we proceed, professionals seeking a robust understanding will discover the intricacies of XOR, its implementation in Python, and its alignment with other bitwise operations.

Overview

Python, a versatile and widely used programming language, offers a vast range of operators, among which bitwise operations hold a significant place. Among these, XOR stands out due to its unique properties and widespread applications. In essence, XOR is an operation that compares bits, returning a result of 1 for differing bits and 0 for identical ones.

This tutorial aims to take professionals on a comprehensive journey: starting from understanding the fundamental essence of XOR in Python to its implementation and relationship with other bitwise operators. As we unfold, we'll also address its practical applications, solidifying its prominence in Python programming.

A Deep Dive into XOR in Python

In Python, XOR stands for Exclusive OR and is not just another logical operation. At its core, Exclusive OR in Python serves as a binary operator that returns true or 1 whenever the number of 1's in the operands is odd. If the number of 1’s is even, it returns false or 0. In simpler terms, if the bits being compared are different, the result is true; otherwise, it’s false.

Properties of XOR:

Understanding the properties of XOR Python is essential for its proper utilization:

1. Commutativity: This property highlights the interchangeability of the operands. Essentially, the order of the operands does not affect the output.

  • A XOR B = B XOR A

2. Associativity: Associativity emphasizes that while grouping the operands in any order, the outcome remains unchanged.

  • A XOR (B XOR C) = (A XOR B) XOR C

3. Identity: In the context of XOR, the identity element is 0. When a bit is XORed with 0, the result is the bit itself.

  • 0A XOR 0 = A

4. Self-Inverseness: An element XORed with itself will always return 0.

  • A XOR A = 0

Operand A

Operand B

A XOR B

0

0

0

0

1

1

1

0

1

1

1

0

Use Cases of XOR:

1. Encryption: XOR's reversibility property makes it indispensable in cryptography. When data is XORed with a key, it becomes encrypted. Repeating the XOR operation with the same key decrypts it, ensuring data confidentiality in communications.

2. Parity: XOR aids in error detection, especially during data transmission. By checking if the number of set bits is even or odd, it's possible to detect single-bit errors.

3. Data Comparison: XOR provides an efficient mechanism to identify differences between two sets of data. When two corresponding bits from different data sets are XORed, a result of 1 indicates a disparity, aiding in tasks like image comparison or file integrity checks.

Example of Bitwise XOR in Python

binary_str1 = "1010"
binary_str2 = "1100"

num1 = int(binary_str1, 2)  # Convert binary string to integer
num2 = int(binary_str2, 2)

result = num1 ^ num2

result_binary = bin(result)[2:]  # Convert integer result back to binary string (remove '0b' prefix)

print("Result of XOR:", result_binary)

Explanation:

  • binary_str1 and binary_str2 are two binary strings representing numbers.

  • num1 is obtained by converting binary_str1 to an integer using the int() function with base 2 (binary).

  • num2 is obtained by converting binary_str2 to an integer using the same approach.

  • The result is calculated by performing a bitwise XOR operation between num1 and num2.

  • result_binary is created by converting the integer result back to a binary string using the bin() function, and then removing the '0b' prefix.

  • The code prints the final result of the bitwise XOR Python operation in binary form.

Other Bitwise Operators in Python With Examples 

Bitwise AND operator

binary_str1 = "1010"
binary_str2 = "1100"

num1 = int(binary_str1, 2)  # Convert binary string to integer
num2 = int(binary_str2, 2)

result = num1 & num2

result_binary = bin(result)[2:]  # Convert integer result back to binary string (remove '0b' prefix)

print("Result of AND:", result_binary)

Explanation:

  • binary_str1 and binary_str2 are two binary strings representing numbers.

  • num1 is obtained by converting binary_str1 to an integer using the int() function with base 2 (binary).

  • num2 is obtained by converting binary_str2 to an integer using the same approach.

  • The result is calculated by performing a bitwise AND operation between num1 and num2.

  • result_binary is created by converting the integer result back to a binary string using the bin() function, and then removing the '0b' prefix.

  • The code prints the final result of the AND operation in binary form.

Bitwise OR operator 

binary_str1 = "1010"
binary_str2 = "1100"

num1 = int(binary_str1, 2)  # Convert binary string to integer
num2 = int(binary_str2, 2)

result = num1 | num2

result_binary = bin(result)[2:]  # Convert integer result back to binary string (remove '0b' prefix)


print("Result of OR:", result_binary)

Explanation:

  • binary_str1 and binary_str2 are two binary strings representing numbers.

  • num1 is obtained by converting binary_str1 to an integer using the int() function with base 2 (binary).

  • num2 is obtained by converting binary_str2 to an integer using the same approach.

  • The result is calculated by performing a bitwise OR operation between num1 and num2.

  • result_binary is created by converting the integer result back to a binary string using the bin() function, and then removing the '0b' prefix.

  • The code prints the final result of the OR operation in binary form.

Logical NOT Operator in Python Example

a = 5

result = ~a

print("Binary representation of", a, ":", bin(a)[2:])  # Removing '0b' prefix
print("Binary representation of ~", a, ":", bin(result)[3:])  # Removing '0b' prefix and considering sign bit

Explanation:

  • a is assigned the value 5.

  • result is assigned the value of bitwise NOT (~) operation on a, which inverts the bits of a.

  • The first print statement displays the binary representation of a, removing the '0b' prefix using slicing.

  • The second print statement displays the binary representation of the result. To consider the sign bit (the leftmost bit) in the result, it uses slicing to remove the '0b' prefix and starts from the third bit (index 3) onward.

Shift Operators 

Right shift

a = 10
shift_amount = 2

result = a >> shift_amount

print("Binary representation of", a, ":", bin(a)[2:])  # Removing '0b' prefix
print("Binary representation of right shift result:", bin(result)[2:])  # Removing '0b' prefix

Explanation:

  • a is assigned the value 10.

  • shift_amount is assigned the value 2, indicating the number of positions to shift the bits to the right.

  • result is calculated by performing a bitwise right shift (>>) operation on a by the amount specified in shift_amount.

  • The first print statement displays the binary representation of a, removing the '0b' prefix using slicing.

  • The second print statement displays the binary representation of the result after the right shift operation, again removing the '0b' prefix using slicing.

For a = 10 and shift_amount = 2, the binary representation of 10 is 1010, and the result of right-shifting 10 by 2 positions is 0010, which is 2 in decimal.

Left shift 

a = 5
shift_amount = 2

result = a << shift_amount

print("Binary representation of", a, ":", bin(a)[2:])  # Removing '0b' prefix
print("Binary representation of left shift result:", bin(result)[2:])  # Removing '0b' prefix

Explanation:

  • a is assigned the value 5.

  • shift_amount is assigned the value 2, indicating the number of positions to shift the bits to the left.

  • result is calculated by performing a bitwise left shift (<<) operation on a by the amount specified in shift_amount.

  • The first print statement displays the binary representation of a, removing the '0b' prefix using slicing.

  • The second print statement displays the binary representation of the result after the left shift operation, again removing the '0b' prefix using slicing.

For a = 5 and shift_amount = 2, the binary representation of 5 is 101, and the result of left-shifting 5 by 2 positions is 10100, which is 20 in decimal.

Bitwise Operator Overloading 

class CustomNumber:
    def __init__(self, value):
        self.value = value
    
    def __and__(self, other):
        return CustomNumber(self.value & other.value)
    
    def __or__(self, other):
        return CustomNumber(self.value | other.value)
    
    def __xor__(self, other):
        return CustomNumber(self.value ^ other.value)
    
    def __invert__(self):
        return CustomNumber(~self.value)
    
    def __str__(self):
        return str(self.value)

# Example usage
num1 = CustomNumber(10)
num2 = CustomNumber(7)

result_and = num1 & num2
result_or = num1 | num2
result_xor = num1 ^ num2
result_not = ~num1

print("num1:", num1)
print("num2:", num2)
print("Result of AND:", result_and)
print("Result of OR:", result_or)
print("Result of XOR:", result_xor)
print("Result of NOT for num1:", result_not)

Explanation:

  • The CustomNumber class is defined with an __init__ method that initializes an instance with a value.

  • The class overloads the bitwise AND (&), OR (|), XOR (^), and inversion (~) operators by defining corresponding methods (__and__, __or__, __xor__, and __invert__).

  • The __and__, __or__, and __xor__ methods perform the respective bitwise operations on the value of the current instance and the value of another instance, returning a new instance of CustomNumber with the result.

  • The __invert__ method performs a bitwise inversion of the value of the current instance, returning a new instance of CustomNumber with the inverted value.

  • The __str__ method is defined to provide a string representation of the instance.

  • Example instances num1 and num2 of CustomNumber class are created with values 10 and 7.

  • The overloaded &, |, ^, and ~ operators are used to perform bitwise operations between num1 and num2, resulting in result_and, result_or, result_xor, and result_not.

  • The results of the operations, as well as the values of num1 and num2, are printed using print statements.

Conclusion

The journey of understanding XOR function in Python is a testament to the depth and versatility Python offers as a programming language. Through this tutorial, we've uncovered the layers on the XOR operation, revealing its essence, significance, and integration within Python's robust suite of bitwise operators. Its unique ability to handle bits offers solutions in areas like data encryption, error detection, and more. 

As the landscape of programming evolves, tools like XOR remain consistent in their importance. Finally, for those motivated to delve deeper and further upskill, consider exploring the advanced courses offered by upGrad. Embrace the ever-evolving realm of Python and ensure your skills remain both relevant and cutting-edge.

FAQs

1. What role does the XOR operator play in cryptography?

XOR, recognized for its unique reversibility feature, is pivotal in cryptography. It's not just a simple bitwise operation; XOR is central to encryption and decryption in several cryptographic schemes. Its property of transforming data without losing the original information makes it an effective tool in secure data transmission methodologies.

2. How do right and left shift operator in Python differentiate?

In the context of Python's bitwise operations, the left shift (<<) operator works by effectively pushing the bits of a number towards the left. On the other hand, the right shift (>>) operator does the exact opposite by shifting the bits towards the right. Both serve unique functionalities and often come in handy in binary operations.

3. Is string XOR possible in Python?

Direct Python XOR string operations using the native libraries isn't straightforward. Python doesn’t inherently support string XOR. However, a commonly used workaround is converting strings into byte sequences. Post this conversion, one can efficiently apply the bitwise XOR operation to obtain the desired results, providing a method to manipulate strings at the bit level.

4. How does XOR differ from the bitwise or in Python operator?

The XOR and bitwise OR are two distinct operations, each with its defining characteristics. While Python XOR operator tries to return a '1' bit for positions where the corresponding bits differ, the bitwise OR (|) operator has a broader application. It gives a '1' in scenarios where at least one of the bits in the operands is '1'. This difference underpins the unique utilities of each operation in programming.

Leave a Reply

Your email address will not be published. Required fields are marked *