Kodeclik Logo

Our Programs

Courses

Gifting

Learn More

Schedule

Kodeclik Blog

Shifting octets in Python

An octet is a unit of digital information consisting of exactly eight bits. While often used synonymously with a byte, the term octet is more precise as it always represents 8 bits, whereas historically, bytes could vary in size. One octet can represent values from 0 to 255 (binary 00000000 to 11111111).

The left shift (<<) and right shift (>>) operators in Python can be used to manipulate octets. Here is a very simple program to illustrate the idea:

In this code, we start with a binary number (that's a number made up of just 0s and 1s) written as 0b10101010 - the '0b' at the start just tells Python it's a binary number. The code then prints this number in two ways: as an 8-digit binary number and as the regular decimal number you're used to seeing. Note that 10101010 in binary is 170 because 128 (1×2⁷) + 0 (0×2⁶) + 32 (1×2⁵) + 0 (0×2⁴) + 8 (1×2³) + 0 (0×2²) + 2 (1×2¹) + 0 (0×2⁰) = 128 + 32 + 8 + 2 = 170.

Then comes the fun part: we use '<<' which is like telling the computer "slide all the digits one space to the left and put a zero at the end." The '& 0xFF' part makes sure our number stays as 8 digits. The “<< 1” means we want to shift it by one position.

We do this sliding action twice, and each time we print out what our new number looks like in both binary and decimal. It's similar to how when you multiply by 10 in regular math, you add a zero at the end - but here we're working with binary numbers and sliding bits instead!

The output will be:

How to shift octets in Python

Let us write some more generic programs to shift either left or right and shift a specified number of steps in one stroke! Here are three different programs.

Method 1: Using Bitwise Operators

Below is a program that generalizes the positions and directions of shifting octets in Python.

As mentioned earlier, this code implements a binary shift operation on an 8-bit value (octet), with the ability to shift either left or right by a specified number of positions. The function takes three parameters: the value to shift, the number of positions to shift, and the direction of the shift. Before performing the shift operation, it prints the original binary value formatted as an 8-bit string for clarity.

After performing the shift operation, the function applies a bitwise AND with 0xFF (11111111 in binary) to ensure the result stays within 8 bits, preventing any overflow. The function then prints the resulting binary value after the shift operation, clearly showing how the bits have moved in the specified direction. For a left shift, zeros are added on the right, while for a right shift, zeros are added on the left, as demonstrated in the output where 10101010 becomes 10101000 when shifted left by 2 positions, and 00101010 when shifted right by 2 positions.

The output will be:

Method 2: Use Binary String Manipulation

Here is a second approach that implements a binary shift operation using string manipulation rather than traditional bitwise operators.

For left shifts, the program slices the binary string from the positions index to the end (binary[positions:]) and concatenates zeros at the end ('0' * positions). For example, shifting "10101010" left by 2 positions removes the first two digits and adds two zeros at the end, resulting in "10101000". Conversely, for right shifts, it prepends the specified number of zeros to the front and removes the same number of digits from the end of the string.

The function maintains the 8-bit format throughout the operation and converts the resulting binary string back to an integer using int(shifted, 2), where the base-2 parameter indicates binary conversion. The print statements provide visual feedback by showing the original binary representation and the shifted result, making it easier to understand how the bits are moving. This string manipulation approach, while perhaps not as computationally efficient as bitwise operations, offers a more intuitive way to visualize and understand binary shifts, especially for educational purposes.

The output will be:

Method 3: Use a class-based approach

Finally, here is an OctetShifter class that takes an object-oriented approach to handling binary shift operations:

The class initializes with a value that's forced to be 8 bits (an octet) using the & 0xFF operation. This ensures we're always working with numbers between 0-255. Think of it like having a digital display with exactly 8 light bulbs that can each be either on (1) or off (0).

When you create a new OctetShifter with shifter = OctetShifter(0b10101010), it stores this binary number internally, ensuring it's only 8 bits long. Then methods like shift_left() and shift_right() implement the desired functionality, similar to Method 1 above.

The output will be the same as before:

Each shift operation creates a new instance of OctetShifter, allowing you to keep track of multiple states if needed, while the print statements show you exactly what's happening at each step of the transformation.

Applications of bit shifting

Bit shifting operations find extensive application in various areas of computer programming, particularly in scenarios where performance and memory optimization are crucial. In low-level programming and embedded systems, shifting is commonly used for fast multiplication and division by powers of two, as shifting left by n positions effectively multiplies a number by 2ⁿ, while shifting right divides by 2ⁿ. This technique is especially valuable in gaming and graphics programming, where quick mathematical operations are essential.

In networking and systems programming, bit shifting plays a vital role in data manipulation and storage optimization. Developers use shifts for packing multiple boolean flags into a single byte to save memory and improve data transmission efficiency. This is particularly important in control systems where reducing the number of transmitted data points can significantly improve performance. For instance, status information like on/off states, error conditions, and operational modes can be packed into a single 32-bit word, potentially reducing transmission times from seconds to milliseconds.

Graphics programming frequently employs bit shifting for color manipulation and RGB value processing. When working with color values, shifts help in combining or extracting individual color components efficiently. For instance, building RGBA values from individual components uses bit shifting to position each color channel in its proper position. Additionally, bit shifting is valuable in embedded systems and microcontroller programming where resources are limited, as well as in cryptography and data compression algorithms where efficient bit manipulation is crucial.

Enjoy this blogpost? Want to learn Python with us? Sign up for 1:1 or small group classes.

Kodeclik sidebar newsletter

Join our mailing list

Subscribe to get updates about our classes, camps, coupons, and more.

About

Kodeclik is an online coding academy for kids and teens to learn real world programming. Kids are introduced to coding in a fun and exciting way and are challeged to higher levels with engaging, high quality content.

Copyright @ Kodeclik 2024. All rights reserved.