Submission bcebd956...

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

        uint i;

        while (offset < length) {

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

            uint chunk = 0x3030303030303030303030303030303030303030303030303030303030303030;
            for (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
            i = chunk;
            i &= 0x5050505050505050505050505050505050505050505050505050505050505050;
            i += 0x5050505050505050505050505050505050505050505050505050505050505050;
            i &= 0x9090909090909090909090909090909090909090909090909090909090909090;
            i /= 0x10;

            // 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;

            chunk += i;

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

            outputOffset += chunkLength;
            i = outputOffset;
            while(chunk != 0) {
                output[--i] = byte(chunk);
                chunk /= 0x10000;
            }
        }
    }
}