3

Let's say I have the

array = [1,2,3,4]

What I want is NOT to convert to the number 1234; but to take the bits of 1, 2, 3 and 4, concatenate them and convert back to a number.

In other words, I would have to perhaps convert each number/digit to binary, concatenate them and then convert back to a number.

Therefore, 1,2,3,4 would be 00000001, 00000010, 00000011, 00000100 respectively. Concatenating them would lead to 00000001000000100000001100000100 which converted to an unsigned int would be 16909060

Keep in mind that the digits from the array come from ord(characters), so they should be 8bits in length, therefore concatenated should lead to a 32bit number

How would I do that?

4
  • " ... convert each number/digit to binary, concatenate them and then convert back to a number" for array is your desired result [1, 10, 11, 100] => 11011100=> 220? Commented Apr 25, 2015 at 12:17
  • Please edit your question to show your expected result. Commented Apr 25, 2015 at 12:18
  • @GordThompson I just added the desired result for the given example Commented Apr 25, 2015 at 12:23
  • what if array contains numbers greater than 255? (binary representation will contain 9+ bits) Commented Apr 25, 2015 at 12:58

5 Answers 5

4

In this simple case perhaps this suffices:

result = array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3]

For example:

array = [1, 2, 3, 4]
result = array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3]
print result

Prints this:

16909060
Sign up to request clarification or add additional context in comments.

3 Comments

No idea why this was downvoted. It seems completely correct. All the other answers are using complicated constructs, whereas this answer shows how simple it is.
This is amazingly simple. May I ask if there's a way to do it in reverse? So given the 32bit integer, split it into 4 8bit integers? I'm thinking maybe result >> 24 would give the first number?
To do it in reverse, you just need to use bitmasks: result & 0xff000000 yields array[0], result & 0x00ff0000 yields array[1] and so on.
1
sum([v << i * 8 for i, v in enumerate(reversed(array))])

6 Comments

it actually is - there is nothing here which requires any explanation - enumerate/reversed can be looked up in python stdlib docs, list comprehension is explained in any python tutorial/book and, I believe, any python dev understand it.
Nearly every question is answerable here by google, the main function of the site is to make this googling phase of the problem solving easier.
explanation is required for complex pieces of code. this one is as simple as it could be.
@Veedrac I am sorry - I found this answer in the "low quality posts" queue, which is - as you can see - quite large. Most people doesn't even comment similar posts, only votes to close/delete it. I commented, trying to advice iced. Looks at least 3 people agreed with it. Maybe it wasn't enough polite, I am sorry for that, (also I am sorry, iced) my goal was to give an advice and not to hurt him. Next time I will comment your more polite version.
I really don't care about phrasing, no need to be sorry. though I still don't agree with you and them 3 others, though I do understand that you commented without trying to understand question/answer.
|
1

The usual way to manipulate arrays of bytes in Python is with the struct module. Beware of the byte order, if necessary.

Python 3

>>> import struct
>>> i, = struct.unpack("<i", bytes([1, 2, 3, 4]))
>>> i
67305985
>>> 

Python 2 & 3

>>> import struct
>>> i, = struct.unpack("<i", struct.pack("4B", *[1, 2, 3, 4]))
>>> i
67305985
>>> 

5 Comments

Umm that construct exactly returns struct.error: unpack requires a string argument of length 4. Is your solution perhaps unique to Python 3? I'm using Python 2.7
Yes, bytes in Python 3 refers to what was the str type in Python 2 (as Python 3 str is what was unicode in Python 2). For Python 2, use struct.pack("4B", *array) instead of bytes(array).
Does not qualify as an answer. It's possible that this code is a good solution, but it is sufficiently obscure to warrant an explanation.
This uses the host computer's byte order which might not be what the OP expects.
Though that would be sufficient to put OP on the right track, but anyway. I improved the answer. Thanks for you comments :)
0
array = [1,2,3,4]
new = []
for number in array:
    bits = bin(number).split('b')[1]
    #transform your number into a binary number (like 0b001), transforms that binary into an array split at b, so [0, 001] and takes the second number of that.
    while len(bits) < 8:
        bits = '0' + bits
        #turns the newly created binary number into an 8 number one
    new.append(bits)
output = '0b'
for item in new:
    output += item
    #puts all the binary's together to form a new, 32 bit binary
output = int(output, 2)
#turns the binary string an integer

using strings for this might not be the cleanest method, but it works.

Comments

0

If you prefer one line

>>> int("".join([bin(x)[2:].zfill(8) for x in a]),2)
16909060

Or step by step

Step 1. convert numbers to binary strings, excape 0bs

>>> a  = [1,2,3,4]
>>> b = [bin(x)[2:] for x in a]
>>> b
['1', '10', '11', '100']

Step 2. fill elements with zeros (zfill)

>>> c = [i.zfill(8) for i in b]
>>> c
['00000001', '00000010', '00000011', '00000100']

Step 3. join elements to make a new string

>>> d = "".join(c)
>>> d
'00000001000000100000001100000100'

Step 4. convert to 10 base number

>>> int(d,2)
16909060

2 Comments

same inefficient as @Gord's answer.
@iced i read your comment under gord's answer. for general approach you are right - if you are dealing with bits you should use bit methods. but in this case(for numbers under 256 (which both solutions are limited to this bound), there is no matter which one you use. both take same time to spit a result. and my code is just equivalent to saying "hey mate you can also use this", nothing more :) btw, i am a philosophy researcher, not a software engineer :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.