Submission 91884fc3...

ChallengeHex decoder
Submitter0x53b21be84eece2e...
Submitted at2018-59-28
Gas used971807
/**
 * 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.
     */

    //  1793429
    //  1507157

//    0     1332 Infinity
//    8     4222 1055.50
//  128    41725 651.95
//  256    82040 640.94
//  512   162723 635.64
// 1024   324307 633.41
// 2048   648342 633.15
// Total gas for HexDecoder: 1264691


// Solc optimizer at 200 runs optimizes
// 0x100000000000000000000000000000000000000000000000000000000000000
// to
// exp(0x2, 0xf8)
// This is super expensive in runtime and we don't want that.
// aparently doing more type casts makes compiler not optimize it 
    function decode(string input) public pure returns(bytes output) {
        bytes memory inp = bytes(input);
        uint len = inp.length / 2;
        // uint16 b;

        // uint8 b1;
        // uint8 b2;
        
        byte b1;
        byte b2;
        byte tmp;
        byte tmp2;

        output = new bytes(len);

        // uint i = 0;
        // i--;
        // j--;
        for (uint j = 0; j < len; j++) {
            // bytes2 b = (bytes2(inp[i * 2]) << 8) ^ bytes2(inp[i * 2 + 1]);
            // b = ((b & 0xf0f) ^ ((b & 0x4040) >> 6) ^ (b & 0x4040));
            // output[++j] = byte(b1 + b2);
            // output[i] = byte(uint8(inp[i * 2]) + uint8(inp[i * 2 + 1]));
            
            
            // b1 = uint8(inp[j + j]);
            // b1 = ((b1 & 0xf) + (b1 & 64) / 7) * 16;
            // b2 = uint8(inp[j + j + 1]);
            // output[j] = byte(b1 + (b2 & 0xf) + (b2 & 64) / 7);

            b1 = inp[j + j];
            tmp = (b1 & 0x40) >> 6;
            b2 = inp[j + j + 1];
            tmp2 = (b2 & 0x40) >> 6;
            output[j] = byte(uint8(((b1 & 0xf) << 4) ^ (b2 & 0xf)) + uint8((tmp << 4) ^ tmp2) * 9);
        }
        return output;
    }
}