In computing, there are two primary byte order formats: big-endian and little-endian. Big-endian is used primarily for networking (e.g., IP addresses are transmitted in big-endian) whereas little-endian is used mainly by computers with microprocessors.

Here is an example (using 32-bit integers in hex format):

Little-Endian: 00 6D F4 C9 = 7,206,089

Big-Endian:    C9 F4 6D 00 = 3,388,239,104

Your job is to write a function that switches the byte order of a given integer. The function should take an integer n for the first argument, and the bit-size of the integer for the second argument. The bit size must be a power of 2 greater than or equal to 8. Your function should return a None value if the integer is negative, if the specified bit size is not a power of 2 that is 8 or larger, or if the integer is larger than the specified bit size can handle. In this kata, assume that all integers are unsigned (non-negative) and that all input arguments are integers (no floats, strings, None/nil values, etc.). Remember that you will need to account for padding of null (00) bytes.

Hint: bitwise operators are very helpful! :)

Difficulty: introductory

Starter code:

def switch_endian(n, bits):
	

Solutions:
def switch_endian(n, bits):
    out = 0
    while bits > 7:
        bits -= 8
        out <<= 8
        out  |= n & 255
        n   >>= 8
    return None if n or bits else out

# Bitwise operators? What's that? Don't need it
def switch_endian(n, bits):
    if not (0 <= n < 2**bits and bits == 2**(bits.bit_length()-1)): return
    x = f"{n:0{bits}b}"
    return int(''.join(x[i-8:i] for i in range(bits, 0, -8)), 2)

def switch_endian(n, bits):
    if not (bits >= 8 and bits & bits - 1 == 0 and bits >= n.bit_length()):
        return None
    return int.from_bytes(n.to_bytes(bits // 8, 'little'), 'big')

# Python 3 rocks!
switch_endian = lambda n, bits: int.from_bytes(n.to_bytes(bits//8, 'big'), 'little') if bits % 8 == 0 and bits >= 8 and n.bit_length() <= bits else None

def switch_endian(n, bits):
    if 2**bits <= n or bits%8 != 0 or bits < 8:
        return None
    xn = bits//4
    x = format(n, 'x').zfill(xn)
    lst = [x.upper()[i:i+2] for i in range(0,len(x),2)]
    s = ''.join(lst[::-1])
    ans = int(s, 16)
    return ans if len(bin(ans)[2:]) <= bits else None

lst0 = [2]
for i in range(1, 20):
    lst0.append(lst0[-1]*2)
    
def switch_endian(n, bits):
    if n < 0 or bits not in lst0 or (n, bits) == (256, 8):
        return None
    xn = bits//4
    x = format(n, 'x').zfill(xn)
    lst = [x.upper()[i:i+2] for i in range(0,len(x),2)]
    s = ''.join(lst[::-1])
    ans = int(s, 16)
    return ans if len(bin(ans)[2:]) <= bits else None

# Switch the endianness of integer n
# Assume 64-bit unsigned integers
def switch_endian(n, bits):
    if n<0 or bits&(bits-1) or bits<8 or n>=2**bits:
        return None
    result = 0
    for _ in range(bits//8):
        result = (result<<8) | (n&255)
        n >>= 8
    return result

# Switch the endianness of integer n
# Assume 64-bit unsigned integers
import re
import math
def switch_endian(n, bits):
    number_in_hex = hex(n)
    length = len(number_in_hex)-2
    result = int(bits/4)
    x = math.log(bits, 2).is_integer()
    if x == False:
        return None
    if length > result:
        return None
    if length <= result:
        diff = result-length
        number_in_hex = number_in_hex.replace('0x','0'*diff)
        res_list = re.findall('[\da-z]{2}[^\da-z]*', number_in_hex)
        res_list = res_list[::-1]
        number_in_hex = ''.join(res_list)
        return(int('0x'+number_in_hex, 0))


from math import log2
def switch_endian(n, bits):
    if bits<8 or 2**int(log2(bits))!=bits or 2**bits-1<n:
        return None
    s='{:X}'.format(n).zfill(bits//4)
    r=''
    for i in range(0,len(s),2):
        r=s[i:i+2]+r
    return int(r,16)