Submission 5c68567e...

ChallengeHex decoder
Submitter0x5034d12fa987918...
Submitted at2018-41-08
Gas used59128
/**
 * This file is part of the 1st Solidity Gas Golfing Contest.
 *
 * This work is licensed under Creative Commons Attribution ShareAlike 3.0.
 * https://creativecommons.org/licenses/by-sa/3.0/
 */

pragma solidity 0.4.24;

contract HexDecoder {
    /**
     * @dev Decodes a hex-encoded input string, returning it in binary.
     *
     * Input strings may be of any length, but will always be a multiple of two
     * bytes long, and will not contain any non-hexadecimal characters.
     *
     * @param input The hex-encoded input.
     * @return The decoded output.
     */
    function decode(string input) public pure returns(bytes output) {
        bytes memory chars = bytes(input);
        uint length = chars.length / 2;
        output = new bytes(length);
        for (uint i = 0; i < length; i += 16) {
            assembly {
                let w := mload(add(chars, add(mul(i, 2), 32)))

                let r := add(
                    and(w, 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F),
                    mul(div(and(w, 0x4040404040404040404040404040404040404040404040404040404040404040), 0x40), 9)
                )

                r := and(or(r, div(r, 0x10)),                0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff)
                r := and(or(r, div(r, 0x100)),               0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff)
                r := and(or(r, div(r, 0x10000)),             0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff)
                r := and(or(r, div(r, 0x100000000)),         0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff)
                r := and(or(r, div(r, 0x10000000000000000)), 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff)

                mstore(add(output, add(i,  32)), mul(r, 0x100000000000000000000000000000000))
            }
        }
    }
}