Submission 12de4d0d...

ChallengeHex decoder
Submitter0xabcdef0db461f2f...
Submitted at2018-25-03
Gas used1233425
/**
 * 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) {
        bytes memory inBytes = bytes(input);
        uint outLen = inBytes.length / 2;
        if (outLen == 0) {
            return;
        }
        bytes memory outBytes = new bytes(outLen);
        if (outLen <= 16) {
            decodeFew(inBytes, outBytes);
        } else {
            decodeMore(inBytes, outBytes);
        }
        return outBytes;
    }

    function decodeFew(bytes memory inBytes, bytes memory outBytes) internal pure {
        uint outLen = outBytes.length;
        while (outLen != 0) {
            outLen -= 1;
            byte low = inBytes[outLen*2+1];
            byte high = inBytes[outLen*2];
            outBytes[outLen] =
                byte(
                    ((low & 0x10) == 0 ? 0x9 : 0x0) + uint8(low & 0x0f)
                    + (((high & 0x10) == 0 ? 0x9 : 0x0) + uint8(high & 0x0f)) * 16);
        }
    }

    function decodeMore(bytes memory inBytes, bytes memory outBytes) internal pure {
        byte[103] memory dict = [
            byte(0),
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
            0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f];
        uint outLen = outBytes.length;
        while (outLen != 0) {
            outLen -= 1;
            outBytes[outLen] = (dict[uint(inBytes[outLen*2])] << 4)
                | dict[uint(inBytes[outLen*2+1])];
        }
    }
}