hamidfzm
hamidfzm

Reputation: 4685

Python bitwise operation on large binary strings

I want to perform bitwise operation on binary strings with length more than 100 zeros and ones. I know i can convert them using something like int('1'*100, 2) which prints 1267650600228229401496703205375L with L character at the end. Then use python bitwise operators but I think it's a bad idea to convert them into integer. Is there any other way to do this?

Upvotes: 5

Views: 7368

Answers (3)

Pogger
Pogger

Reputation: 382

Here is one more way to do it optimally.

bin(int("1100",2)|int("1010", 2))

Upvotes: 3

Resonance
Resonance

Reputation: 3786

I'm guessing that you do not like the idea of using integers because it obfuscates your underlying data. Plus it makes it difficult to work with strings that start with '0' (because they trimmed off when converting to an integer), not to mention the subtleties of signed integers and endianness.

Try using the bitarray module, can be installed with pip: pip install bitarray.

from bitarray import bitarray
ba1 = bitarray('0' + '1'*100)
ba2 = bitarray('1' + '0'*100)

len(ba1)  # 101
len(ba2)  # 101
ba1[0]    # False
ba2[0]    # True

ba1 | ba2  # bitarray('1111111111.......)

# get your string back
ba1.to01()  # "01111111......."

I can't speak for the efficiency. But at least it feels clear as to what you are working with.

Also works in python3

Docs: https://pypi.python.org/pypi/bitarray/0.8.1

Upvotes: 4

grochmal
grochmal

Reputation: 3027

Do not do bitwise operations on strings of 0s and 1s that is plain bad and slow. You shall convert the strings to actual numbers as then the processing of several bits is done at once. There is nothing wrong with:

int('1'*128,2) & int('1'*128,2)

But if you already have strings of 0s and 1s and you want control over the bitwise operation on parts of the strings. You can do the following:

l = '1'*1024
r = '1'*1024
print map(lambda x: x[0] & x[1], [(int(l[i:i+64], 2), int(r[i:i+64], 2)) for i in range(0,1024,64)])

This effectively uses the & over small chunks (64 bits) of the string, from left to right.

You can call bin() on each result and concatenate them back if you need a string. (taking care to remove the starting 0b at the start of the output of bin())


python 3 version:

l = '1'*1024
r = '1'*1024
print(list(map(lambda x: x[0] & x[1], [(int(l[i:i+64], 2), int(r[i:i+64], 2)) for i in range(0,1024,64)])))

Upvotes: 0

Related Questions