Solidity Bytes32 – Convert Bytes32 to Ordered Bytes2, Bytes4, and More

bytesbytes32solidity

For example,
I need to slice my bytes32 variable to chunks, and put result into 5 variables, saving the order, bytes2, bytes2, bytes2, bytes2, bytes8, bytes1 (aka byte), the order should be saved and I don't really care about the rest of bytes.

Is solidity has some tools for that? Or it is only possible with bit operations.

I found some difficulties working with this low-level types.

UPDATE:
So I did prepare this function which parses numBytes bytes from source starting from start byte.

function bytesChunck(bytes32 source, uint start, uint numBytes) constant returns(uint _result){
            uint counter = 0;
            uint result;

            for(uint i = 0; i < numBytes; i++) {
                result += uint8(source[start + i]);
            }
            return result;
            // 
    }

then I just convert result to needed bytes, like bytes8(result). But it seems to be overflowed, since if I have like 8 bytes it first bytes always zeros. Any ideas? 🙂

Thank you.

Best Answer

Your question is not clear enough. When you want to split 32 bytes into 5 variables that have a total length of 2+2+2+2+8+1 = 17 you should specify what bytes you want to be chunked (bytes from left or bytes from right).

I wrote an example that solves your problem as far as I could understand it. Comment the answer - explain what you exactly need, and I'll change the code.

pragma solidity ^0.4.0;

contract BytesChunkTest
{
    bytes32 constant public test_source=0x000000000000000000ff11223344556677889900aabbccddeeff;

    bytes32 constant mask1 = 0xff00000000000000000000000000000000000000000000000000000000000000;
    bytes32 constant mask2 = 0xffff000000000000000000000000000000000000000000000000000000000000;
    bytes32 constant mask8 = 0xffffffffffffffff000000000000000000000000000000000000000000000000;
    uint    constant main_shift=15;

    function sourceToChunk(bytes32 source) constant
    returns
        (
            bytes2 r1_2,
            bytes2 r2_2,
            bytes2 r3_2,
            bytes2 r4_2,
            bytes8 r5_8,
            bytes1 r6_1
        )
    {

        r1_2 = bytes2(source<<(main_shift*8)&mask2);
        r2_2 = bytes2((source<<(main_shift+2)*8)&mask2);
        r3_2 = bytes2((source<<(main_shift+4)*8)&mask2);
        r4_2 = bytes2((source<<(main_shift+6)*8)&mask2);
        r5_8 = bytes8((source<<(main_shift+8)*8)&mask8);
        r6_1 = bytes1((source<<(main_shift+16)*8)&mask1);
    }


    function test() constant
    returns
        (
            bytes2,
            bytes2,
            bytes2,
            bytes2,
            bytes8,
            bytes1
        )
    {
        return sourceToChunk(test_source);
    }
}