Submission e8f5aca5...

ChallengeHex decoder
Submitterricmoo.firefly.eth
Submitted at2018-08-06
Gas used1054539
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;

            n0 &= 0x5050505050505050505050505050505050505050505050505050505050505050;
if (n0 != 0) {
            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++;

        }
    }
}