bit
bit

Reputation: 99

C function to Python

Can someone help to make Python version of function. Thanks

unsigned char asap_xor(unsigned char *msg, int len) {
    unsigned char xor_val = 0;
    int i;
    xor_val = msg[0];
    for (i = 1; i < len; i++) {
        xor_val ^= msg[i];
    }
    xor_val = 13 ^ xor_val;
    xor_val = xor_val | 0x40;
    return (xor_val);
}

my python version but error

def asap_xor(msg, len):
    xor_val = msg[0]
    for i in range(1, len):
        xor_val ^= msg[i]
    xor_val = byte(13 ^ xor_val)
    xor_val = byte(xor_val | 0x40)
    return (xor_val)

TypeError: unsupported operand type(s) for ^=: 'str' and 'str'

Upvotes: 0

Views: 150

Answers (2)

th33lf
th33lf

Reputation: 2275

Not sure what version of python you are on, but for python 3.5+ or so, this should work:

def asap_xor(msg):        
    xor_val = msg[0]
    for m in msg[1:]:
        xor_val ^= m
    xor_val = (13 ^ xor_val)
    xor_val = (xor_val | 0x40)

    return xor_val

print(asap_xor("test".encode('utf8')))
print(asap_xor(b"test"))

Upvotes: 3

Olvin Roght
Olvin Roght

Reputation: 7812

If your task is to "translate" code from C to Python line by line @th33lf's answer is perfectly fine.

However, you can use built-in features of Python which allows you to implement same logic in one-liner (suggested in this comment):

13 ^ reduce(xor, msg) | 0x40

reduce() iterates over iterable and applies provided function (we used xor()) to every item using result of previous step as first argument.

So pythonic version of your C function is:

from functools import reduce
from operator import xor

def asap_xor(msg):
    return 13 ^ reduce(xor, msg) | 0x40

Note that msg should be an iterable of int values (already said in this comment). If your input value is string you can use str.encode() to convert str to bytes.

If you need to keep len argument (as you've said in this comment) you can pass sliced msg to reduce() (check this comment). I'd set default length argument value to 0 and use islice() only if some non-zero length passed to function.

from functools import reduce
from operator import xor
from itertools import islice

def asap_xor(msg, length=0):
    return 13 ^ reduce(xor, islice(msg, length) if length else msg) | 0x40

Usage:

asap_xor("message".encode())                     # 102
asap_xor("message".encode(), 6)                  # 67
asap_xor(b"message")                             # 102
asap_xor(b"message", 6)                          # 67
asap_xor([109, 101, 115, 115, 97, 103, 101])     # 102
asap_xor([109, 101, 115, 115, 97, 103, 101], 6)  # 67

Upvotes: 4

Related Questions