Submission f8433230...

ChallengeHex decoder
Submittersggc.yuetloo.eth
Submitted at2018-53-05
Gas used1771249
/**
 * 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 j= 0;
        uint len = output.length;
        uint chunks = len - (len%16);

        for(uint i = 0; i < len; ) {
           uint m = (i < chunks? 16 : len - i);
           uint n = m + m;
           j += n;
           uint v = (uint(bytes(input)[j-2])*0x100) | uint(bytes(input)[j-1]);
           for( uint k = 3; k < n; ) {
              v = (v* 0x10000) | (uint(bytes(input)[j-k-1])*0x100) | uint(bytes(input)[j-k]);
              k += 2; 
           }

           // parallel mapping formula: lower byte + (9 for A...F)
           v  =    (v & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f) + 
               (((((v & 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0) & 
                        0x5050505050505050505050505050505050505050505050505050505050505050) + 
                        0x5050505050505050505050505050505050505050505050505050505050505050) & 
                        0x9090909090909090909090909090909090909090909090909090909090909090)/16);
           v = ( v/16 ) | v;
           
           m += i;
           for(; i < m; ++i)
           {
              output[i]   = byte( v );
              v /= 0x10000;
           }
        }
    }
}