Submission 2a459a33...

ChallengeHex decoder
Submitter0x06ae35566bc4c75...
Submitted at2018-31-07
Gas used78539
/**
 * 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);
        output = new bytes(chars.length / 2);
        for (uint i = 0; i < output.length; i += 16) {
            uint w;
            assembly {
               w := mload(add(chars, add(mul(i, 2), 32)))
            }
            uint r =
                (w & 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F) +
                ((w & 0x4040404040404040404040404040404040404040404040404040404040404040) / 0x40) * 9;

            uint tmp = 0;
            tmp = (r ^ (r >> 4)) & 0x00f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f0;
            r ^= (tmp ^ (tmp << 4));
            tmp = (r ^ (r >> 8)) & 0x0000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff00;
            r ^= (tmp ^ (tmp << 8));
            tmp = (r ^ (r >> 16)) & 0x00000000ffff000000000000ffff000000000000ffff000000000000ffff0000;
            r ^= (tmp ^ (tmp << 16));
            tmp = (r ^ (r >> 32)) & 0x0000000000000000ffffffff000000000000000000000000ffffffff00000000;
            r ^= (tmp ^ (tmp << 32));
            tmp = (r ^ (r >> 64)) & 0x00000000000000000000000000000000ffffffffffffffff0000000000000000;
            r ^= (tmp ^ (tmp << 64));

            r <<= 128;
            assembly {
                mstore(add(output, add(i,  32)), r)
            }
        }
    }
}