Submission c63002d3...

ChallengeHex decoder
Submitterzac.creditmint.eth
Submitted at2018-18-10
Gas used37669
pragma solidity ^0.4.23;

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) external view returns(bytes output) {
        assembly {
            mstore(0x40, 0)
            mstore(0x00, no_bytes)
            mstore(0x20, one_word)

            2 0x24 calldataload div
            dup1
            dup2 0x1f and iszero
            no_residual jumpi
            
            no_residual:
            0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 and 0x20 add

            mload dup1 jumpi
            0x44
            0x40
            loop_start:
                dup2 calldataload
                0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                dup2 0xEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF or not
                0x9000000000000000000000000000000000000000000000000000000000000000 mulmod add
                0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F and
                16 dup2 div or
                0x20 mstore
                4 mload 6 mload 8 mload 10 mload 12 mload 14 mload 16 mload 18 mload
                20 mload 22 mload 24 mload 26 mload 28 mload 30 mload 32 mload
                48 mstore8 47 mstore8 46 mstore8 45 mstore8 44 mstore8 43 mstore8 42 mstore8 41 mstore8
                40 mstore8 39 mstore8 38 mstore8 37 mstore8 36 mstore8 35 mstore8 34 mstore8
                33 mload dup2 mstore

                dup2 0x20 add calldataload
                0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                dup2 0xEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF or not
                0x9000000000000000000000000000000000000000000000000000000000000000 mulmod add
                0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F and
                16 dup2 div or
                0x20 mstore
                4 mload 6 mload 8 mload 10 mload 12 mload 14 mload 16 mload 18 mload
                20 mload 22 mload 24 mload 26 mload 28 mload 30 mload 32 mload
                48 mstore8 47 mstore8 46 mstore8 45 mstore8 44 mstore8 43 mstore8 42 mstore8 41 mstore8
                40 mstore8 39 mstore8 38 mstore8 37 mstore8 36 mstore8 35 mstore8 34 mstore8
                33 mload dup2 0x10 add mstore

                0x20 add
                swap1 0x40 add
                swap1
                dup2 calldatasize gt
                loop_start jumpi

            pop pop
            0x20 0x00 mstore
            dup1 0x20 mstore
            0x40 add 0x0000000000000000000000000000000000000000000000000000000000000000
            dup2 mstore

            dup1 0x1f and iszero
            skip jumpi
            0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 and 0x20 add
            skip:
            0
            return

        no_bytes:
            mstore(0x00, 0x20)
            mstore(0x20, 0x00)
            return(0x00, 0x20)
            
        one_word:
            0x44 calldataload

            0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
            dup2 0xEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF or not
            0x9000000000000000000000000000000000000000000000000000000000000000 mulmod add
            0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F and
            16 dup2 div or 0x3f mstore
            0x23 mload 0x25 mload 0x27 mload 0x29 mload 0x2b mload 0x2d mload 0x2f mload 0x31 mload
            0x33 mload 0x35 mload 0x37 mload 0x39 mload 0x3b mload 0x3d mload 0x3f mload
            0x4f mstore8
            0x4e mstore8
            0x4d mstore8
            0x4c mstore8
            0x4b mstore8
            0x4a mstore8
            0x49 mstore8
            0x48 mstore8
            0x47 mstore8
            0x46 mstore8
            0x45 mstore8
            0x44 mstore8
            0x43 mstore8
            0x42 mstore8
            0x41 mstore8

            0x00 dup2 0x40 add mstore
            0x20 0x00 mstore
            dup1 0x20 mstore    // store s at 0x20
            0x60 0 return
        two_words:
        one_byte:
            /* calldataload(0x44)
            0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
            dup2 0xEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEF or not
                // multiply by 2**255 + 2**252, trigger integer overflow so that
                // every 5th bit becomes every (4th + 1st) bit
            0x9000000000000000000000000000000000000000000000000000000000000000
            mulmod
                // combine back into w
            add
            // mask out the top 4 bits of every byte
            0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F and
            
            dup1 1 byte // 0b
            swap1 0 byte      // 0a
            16 mul or   // ab
            0x40 mstore8
            0x00 0x41 mstore
            0x01 0x20 mstore
            0x20 0x00 mstore
            0x60 0x00 return */
        
        two_byte:

        three_byte:

        four_byte:

        five_byte:

        six_byte:

        seven_byte:

        eight_byte:

        nine_byte:

        ten_byte:

        thirty_two_byte:


        sixty_four_byte:


        }
    }
}