Submission b3be2949...

ChallengeHex decoder
Submittersggc.yuetloo.eth
Submitted at2018-44-03
Gas used1791220
/**
 * This contract was a modified version of the original from 
 * https://github.com/arachnid/sggc.git
 *
 * 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) {
        output = new bytes(bytes(input).length / 2);

        uint i= 0;
        uint j= 0;
        uint len = output.length;

        uint chunks = len/4;
        for(uint k = 0; k < chunks; k++) {
           // store bytes in lifo order to ease writing to output array
           uint v = (((((uint(bytes(input)[j+6]) * 256) | uint(bytes(input)[j+7]))* 65536) |
                    ((uint(bytes(input)[j+4]) * 256) | uint(bytes(input)[j+5])))* 4294967296) |
                    (((uint(bytes(input)[j+2]) * 256) | uint(bytes(input)[j+3]))* 65536) |
                    ((uint(bytes(input)[j]) * 256) | uint(bytes(input)[j+1]));

           // parallel mapping 
           v =    (v & 0x0f0f0f0f0f0f0f0f) + 
              (((((v & 0xf0f0f0f0f0f0f0f0)/16) & 
                       0x0505050505050505) + 
                       0x0505050505050505) & 
                       0x0909090909090909);

           output[i]   = byte( ((v&0x0f00)/16) | (v&0x000f));
           v /= 65536;
           output[i+1]   = byte( ((v&0x0f00)/16) | (v&0x000f));
           v /= 65536;
           output[i+2]   = byte( ((v&0x0f00)/16) | (v&0x000f));
           v /= 65536;
           output[i+3]   = byte( ((v&0x0f00)/16) | (v&0x000f));

           j+=8;
           i+=4;
        }

        for(; i < len; i++) {
           v = (uint(bytes(input)[j]) * 256) | uint(bytes(input)[j+1]);
           v = (v & 0x0f0f) + (((((v & 0xf0f0)/16) & 0x0505) + 0x0505) & 0x0909);
           output[i] = byte( ((v&0x0f00)/16) | (v&0x0f));
           j+=2;
        }
    }
}