Submission 2ef29d6a...

ChallengeHex decoder
Submitter0x31efd75bc0b5fba...
Submitted at2018-39-10
Gas used1109151
/**
 * 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/
 */

 // submitted : 2900991 gas
 // improved :  1887762 gas
 //             2036330
 //             2018438
 //             1416217
 //             1415621
 //             1263823
 //             2210934
 //             1230254 


pragma solidity 0.4.24;

contract HexDecoder {

    function mkb(uint len) internal pure returns (bytes b) {
        b = new bytes(len);
    }

    /**
     * @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 len = bytes(input).length >> 1;
        //bytes memory b = bytes(input);
        output = mkb(len);
        uint i = 0;
        uint pos;
        if (len > 8) {
            byte[103] memory lookup;
            byte[103] memory lookdown;
            lookdown[0x31] = 1;
            lookdown[0x32] = 2;
            lookdown[0x33] = 3;
            lookdown[0x34] = 4;
            lookdown[0x35] = 5;
            lookdown[0x36] = 6;
            lookdown[0x37] = 7;
            lookdown[0x38] = 8;
            lookdown[0x39] = 9;
            lookdown[0x41] = 0xa;
            lookdown[0x42] = 0xb;
            lookdown[0x43] = 0xc;
            lookdown[0x44] = 0xd;
            lookdown[0x45] = 0xe;
            lookdown[0x46] = 0xf;
            lookdown[0x61] = 0xa;
            lookdown[0x62] = 0xb;
            lookdown[0x63] = 0xc;
            lookdown[0x64] = 0xd;
            lookdown[0x65] = 0xe;
            lookdown[0x66] = 0xf;

            lookup[0x31] = 0x10;
            lookup[0x32] = 0x20;
            lookup[0x33] = 0x30;
            lookup[0x34] = 0x40;
            lookup[0x35] = 0x50;
            lookup[0x36] = 0x60;
            lookup[0x37] = 0x70;
            lookup[0x38] = 0x80;
            lookup[0x39] = 0x90;
            lookup[0x41] = 0xa0;
            lookup[0x42] = 0xb0;
            lookup[0x43] = 0xc0;
            lookup[0x44] = 0xd0;
            lookup[0x45] = 0xe0;
            lookup[0x46] = 0xf0;
            lookup[0x61] = 0xa0;
            lookup[0x62] = 0xb0;
            lookup[0x63] = 0xc0;
            lookup[0x64] = 0xd0;
            lookup[0x65] = 0xe0;
            lookup[0x66] = 0xf0;



            while (pos < len) {
                output[pos++] = lookdown[uint(bytes(input)[i++])] | lookup[uint(bytes(input)[i++])];
            }

            return;
        }
        uint8 c;
        uint8 total;
        while (pos < len) {
            total = uint8(bytes(input)[i++]);
            if (total < 0x40) 
                total -= 0x30;
            else if (total < 0x60) 
                total -= 0x37;
            else 
                total -= 0x37;
            total = total << 4;
            c = uint8(bytes(input)[i++]);
            if (c < 0x40) 
                total += c - 0x30;
            else if (c < 0x60) 
                total += c - 0x37;
            else 
                total += c - 0x57;
            output[pos++] = byte(total);
        }
    }

    event Loggit(bytes b);

    function test(string s) public {
        bytes memory b = decode(s);
        emit Loggit(b);
    }
}
// 20 1690706
// 0x8f6288d5
// 0000000000000000000000000000000000000000000000000000000000000020
// 0000000000000000000000000000000000000000000000000000000000000004
// 3132333400000000000000000000000000000000000000000000000000000000