Submission 13515e30...

ChallengeHex decoder
Submitterricmoo.firefly.eth
Submitted at2018-05-06
Gas used1049289
pragma solidity 0.4.24;

contract HexDecoder {

    function decode(string input) pure public returns (bytes output) {
        bytes memory inp = bytes(input);
        uint length = inp.length;

        output = new bytes(length / 2);

        uint offset = 0;
        uint outputOffset = 0;

        while (offset < length) {

            uint chunkLength = length - offset;
            if (chunkLength > 32) { chunkLength = 32; }

            uint chunk = 0;
            for (uint i = 0; i < chunkLength; i++) {
                chunk *= 256;
                chunk |= uint(inp[offset + i]);
            }
            offset += chunkLength;

            chunkLength /= 2;

            // "Number 0" (Alpha 9) For letters (0x40 set) put 0x90 in the slot, otherwise 0
            uint n0 = chunk;

            // Take the lowest nibble from each ascii character
            // 0-9: already the correct value
            // A-F: add 9 to the value to offset A (1) -> 10, etc
            chunk &= 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;

            /*
            if (chunk == 0) {
                outputOffset += chunkLength;
                continue;
            }
            */

            n0 &= 0x5050505050505050505050505050505050505050505050505050505050505050;
            n0 += 0x5050505050505050505050505050505050505050505050505050505050505050;
            n0 &= 0x9090909090909090909090909090909090909090909090909090909090909090;
            n0 /= 0x10;

            chunk += n0;

            chunk = (chunk | (chunk / 0x10));


            outputOffset += chunkLength - 1;
            for (uint j = 0; j < chunkLength; j++) {
                output[outputOffset - j] = byte(chunk);
                chunk /= 0x10000;
            }
            outputOffset++;

        }
    }
}