Submission f2bec693...

ChallengeString search
Submitterwicketh.eth
Submitted at2018-57-27
Gas used73978
pragma solidity 0.4.24;

contract IndexOf {

    function () external payable { assembly {
        // indexOf(string haystack, string needle)
        
        // @author Remco Bloemen <[email protected]>
        
        let h := add(calldataload(0x04), 4)
        let n := add(calldataload(0x24), 4)
        let hl := calldataload(h)
        let nl := calldataload(n)
        
        // Empty needle 
        if iszero(nl) {
            mstore(0, 0)
            return(0, 32)
        }
        // Needle longer than haystack
        if gt(nl, hl) {
            mstore(0, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
            return(0, 32)
        }
        
        // Special case for single character needle
        if eq(nl, 1) {
            
            n := and(calldataload(add(n, 1)), 0xFF)
            let mask := not(mul(n, 0x0101010101010101010101010101010101010101010101010101010101010101))
            
            h := calldataload(add(h, 32))
            
            let matc := xor(mask, h)
            matc := and(matc, div(matc, 16))
            matc := and(matc, div(matc, 4))
            matc := and(matc, div(matc, 2))
            matc := and(matc, 0x0101010101010101010101010101010101010101010101010101010101010101)
            
            if iszero(matc) {
                mstore(0, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
                return(0, 32)
            }
            
            let result := 0
            for {} lt(matc, 0x0100000000000000000000000000000000000000000000000000000000000000) {} {
                result := add(result, 1)
                matc := mul(matc, 256)
            }
            
            mstore(0, result)
            return(0, 32)
        }
        
        // General case using hashes
        calldatacopy(0, add(n, 32), nl)
        n := keccak256(0, nl)
        calldatacopy(0, add(h, 32), hl)
        
        let i := 0
        let e := add(sub(hl, nl), 1)
        let hv
        
        loop:
            hv := keccak256(i, nl)
            if eq(n, hv) {
                mstore(0, i)
                return(0, 32)
            }
            i := add(i, 1)
            if eq(i, e) {
                mstore(0, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
                return(0, 32)
            }
            jump(loop)
    }}
}