Skip to content

Instantly share code, notes, and snippets.

@ottodevs
Forked from thomasmaclean/StringToLower.sol
Created September 26, 2017 11:22
Show Gist options
  • Save ottodevs/c43d0a8b4b891ac2da675f825b1d1dbf to your computer and use it in GitHub Desktop.
Save ottodevs/c43d0a8b4b891ac2da675f825b1d1dbf to your computer and use it in GitHub Desktop.
Ethereum/Solidity toLower() equivalent, to transform strings to lowercase
pragma solidity ^0.4.11;
contract StringToLower {
function _toLower(string str) internal returns (string) {
bytes memory bStr = bytes(str);
bytes memory bLower = new bytes(bStr.length);
for (uint i = 0; i < bStr.length; i++) {
// Uppercase character...
if ((bStr[i] >= 65) && (bStr[i] <= 90)) {
// So we add 32 to make it lowercase
bLower[i] = bytes1(int(bStr[i]) + 32);
} else {
bLower[i] = bStr[i];
}
}
return string(bLower);
}
}
@crazyrabbitLTC
Copy link

Hello! Would you mind either creating a ZeppelinOS EVM package out of this code? Or would you mind if I went ahead and did it? It would be very useful as an EVM package.

Here is some more information about EVM packages:
https://blog.zeppelinos.org/state-of-evm-packages-end-of-2018/

@khlilturki97
Copy link

this is solidity 0.5 version

function _toLower(string memory str) internal pure returns (string memory) {
        bytes memory bStr = bytes(str);
        bytes memory bLower = new bytes(bStr.length);
        for (uint i = 0; i < bStr.length; i++) {
            // Uppercase character...
            if ((uint8(bStr[i]) >= 65) && (uint8(bStr[i]) <= 90)) {
                // So we add 32 to make it lowercase
                bLower[i] = bytes1(uint8(bStr[i]) + 32);
            } else {
                bLower[i] = bStr[i];
            }
        }
        return string(bLower);
    }

@BananaNeil
Copy link

Is this deployed somewhere already?

@ottodevs
Copy link
Author

ottodevs commented Jun 2, 2022

Is this deployed somewhere already?

I completely forgot about this.

I am sorry, I don't know. IIRC I never really used it in production.

Maybe we should finally try to add it to ZeppelinOS as a package is there, is there is some demand, but it probably needs more testing and adapt to recent solidity versions.

@milaabl
Copy link

milaabl commented Mar 8, 2024

this is solidity 0.5 version

function _toLower(string memory str) internal pure returns (string memory) {
        bytes memory bStr = bytes(str);
        bytes memory bLower = new bytes(bStr.length);
        for (uint i = 0; i < bStr.length; i++) {
            // Uppercase character...
            if ((uint8(bStr[i]) >= 65) && (uint8(bStr[i]) <= 90)) {
                // So we add 32 to make it lowercase
                bLower[i] = bytes1(uint8(bStr[i]) + 32);
            } else {
                bLower[i] = bStr[i];
            }
        }
        return string(bLower);
    }

This gives unexpected behavior when the string that was passed in _toLowerCase is referenced later in the code, because _toLowerCase doesn't only transform the output, but also modifies the original string and its bytes in the memory.

So here's a fixed "transform string to lower case" version for Solidity above ^0.5.0 (that won't modify the original string in the memory):

function copyBytes(bytes memory _bytes) private pure returns (bytes memory) {
        bytes memory copy = new bytes(_bytes.length);
        uint256 max = _bytes.length + 31;
        for (uint256 i=32; i<=max; i+=32)
        {
            assembly { mstore(add(copy, i), mload(add(_bytes, i))) }
        }
        return copy;
    }

    function _toLowercase(string memory inputNonModifiable) public pure returns (string memory) {
        bytes memory bytesInput = copyBytes(bytes(inputNonModifiable));

        for (uint i = 0; i < bytesInput.length; i++) {
            // checks for valid ascii characters // will allow unicode after building a string library
            require (uint8(bytesInput[i]) > 31 && uint8(bytesInput[i]) < 127, "Only ASCII characters");
            // Uppercase character...
            if (uint8(bytesInput[i]) > 64 && uint8(bytesInput[i]) < 91) {
                // add 32 to make it lowercase
                bytesInput[i] = bytes1(uint8(bytesInput[i]) + 32);
            }
        }
        return string(bytesInput);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment