Solidity Bytes32 – How to Split a Bytes32 Source into Two Halfs and Store in Bytes16

bytesbytes32solidity

I want to split a 32 Byte source: first half in Bytes16 half1; second half in Bytes16 half2. My code works, however only for dynamic array, not with fixed size 16.

pragma solidity ^0.4.8;

contract cut {

    function cutSha(bytes32 source) constant returns (bytes, bytes) {
        bytes memory half1 = new bytes(16);
        bytes memory half2 = new bytes(16);
        for (uint j = 0; j < 16; j++) {
                half1[j] = source[j];
                half2[j] = source[j+16];
        }
        return (half1, half2);
    }
}

Best Answer

It is possible to do this with assembly:

pragma solidity ^0.4.8;

contract c {
    event trace(bytes32 x, bytes16 a, bytes16 b);

    function foo(bytes32 source) {
        bytes16[2] memory y = [bytes16(0), 0];
        assembly {
            mstore(y, source)
            mstore(add(y, 16), source)
        }
        trace(source, y[0], y[1]);
    }
}

For example, converting bytes from the string "what a wonderful world!", produces this after using 2245 gas:

trace[
  "0x77686174206120776f6e64657266756c20776f726c6421000000000000000000",
  "0x77686174206120776f6e64657266756c",
  "0x20776f726c6421000000000000000000"
]

NB: the code relies on the internal data representation that may be subject to change in later versions of Solidity or interfere with Solidity optimizer in an unpredictable ways.