Submission a3c99999...

ChallengeHex decoder
Submitterlogvinov.eth
Submitted at2018-15-24
Gas used967280
/**
 * 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 bInput = bytes(input);
        output = new bytes(bInput.length / 2);
        uint8[] memory mapp = new uint8[](55);
        mapp[1] = 1;
        mapp[2] = 2;
        mapp[3] = 3;
        mapp[4] = 4;
        mapp[5] = 5;
        mapp[6] = 6;
        mapp[7] = 7;
        mapp[8] = 8;
        mapp[9] = 9;
        mapp[17] = 10;
        mapp[18] = 11;
        mapp[19] = 12;
        mapp[20] = 13;
        mapp[21] = 14;
        mapp[22] = 15;
        mapp[49] = 10;
        mapp[50] = 11;
        mapp[51] = 12;
        mapp[52] = 13;
        mapp[53] = 14;
        mapp[54] = 15;
        for (uint i = 0; i < output.length; i++) {
            uint8 b1;
            uint8 b2;
            uint inputPtr;
            assembly {
                inputPtr := add(input, 0x01)
                b1 := mload(add(inputPtr, mul(i, 2)))
                b2 := mload(add(add(inputPtr, mul(i, 2)), 1))
            }
            b1 = mapp[b1 - 48];
            b2 = mapp[b2 - 48];
            /* if(b1 >= 0x30 && b1 <= 0x39) { // 48..57
                b1 = b1 - 0x30; // 48
            } else if(b1 >= 0x41 && b1 <= 0x46) { // 65..90
                b1 = b1 - 0x37; // 55
            } else if(b1 >= 0x61 && b1 <= 0x67) { // 97..122
                b1 = b1 - 0x57; // 87
            }
            if(b2 >= 0x30 && b2 <= 0x39) { // 48..57
                b2 = b2 - 0x30; // 48
            } else if(b2 >= 0x41 && b2 <= 0x46) { // 65..90
                b2 = b2 - 0x37; // 55
            } else if(b2 >= 0x61 && b2 <= 0x67) { // 97..122
                b2 = b2 - 0x57; // 87
            } */
            output[i] = byte((b1 << 4) | b2);
        }
    }
}