Submission ea80b57c...

ChallengeHex decoder
Submitter0xabcdef0db461f2f...
Submitted at2018-13-01
Gas used192583
/**
 * 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) {
        uint outLen;
        assembly { outLen := div(mload(0x80), 2) }
        if (outLen == 0) { return; }
        bytes memory outBytes = new bytes(outLen);
        assembly {
            let inPtr := 0xa0
            let ptrStopLoop := add(0xa0, mload(0x80))
            let tmpVal
            for { } lt(inPtr, ptrStopLoop) { } {
                tmpVal := mload(inPtr)
                tmpVal := add(
                    mul(
                        div(
                            and(tmpVal, 0x4040404040404040404040404040404040404040404040404040404040404040),
                            0x40),
                        0x09),
                    and(tmpVal, 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f))
                tmpVal := mul(tmpVal, 0x110)
                mstore(inPtr, tmpVal)
                inPtr := add(inPtr, 0x20)
            }
            inPtr := sub(ptrStopLoop, 0x21)
            ptrStopLoop := add(outBytes, 0x1f)
            let outPtr := add(add(outBytes, 0x1f), outLen)
            for { } gt(outPtr, ptrStopLoop) { } {
                mstore8(outPtr, mload(inPtr))
                outPtr := sub(outPtr, 0x1)
                inPtr := sub(inPtr, 0x2)
            }
        }
        return outBytes;
    }
}