高橋  花子

高橋 花子

1653303600

Solidityで文字列の長さを見つける方法

Javascriptの世界では、文字列の長さを見つけるのはとても簡単なことでstr.length、それだけです。

しかし、文字列はSolidity内で動作するのにそれほど友好的ではありません。

Solidityでは、文字列は配列内に格納されている文字のグループであり、データをバイト単位で格納します。

文字列型にはlengthメソッドはありません。

Buildspaceのbuild-polygon-ensプロジェクトを実行していて、次のリンクを見つけましたStringUtils.sol

Solidityで文字列の長さを見つける方法を知っていたので、文字列をバイトに変換してその長さを見つけることができます。したがって、実行するのと同じくらい簡単なはずbytes(str).length;ですが、このutilファイルのメソッドは少し異なります。

// SPDX-License-Identifier: MIT
// Source:
// https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/StringUtils.sol
pragma solidity >=0.8.4;library StringUtils {
    /**
     * @dev Returns the length of a given string
     *
     * @param s The string to measure the length of
     * @return The length of the input string
     */
    function strlen(string memory s) internal pure returns (uint256) {
        uint256 len;
        uint256 i = 0;
        uint256 bytelength = bytes(s).length;        for (len = 0; i < bytelength; len++) {
            bytes1 b = bytes(s)[i];
            if (b < 0x80) {
                i += 1;
            } else if (b < 0xE0) {
                i += 2;
            } else if (b < 0xF0) {
                i += 3;
            } else if (b < 0xF8) {
                i += 4;
            } else if (b < 0xFC) {
                i += 5;
            } else {
                i += 6;
            }
        }
        return len;
    }
}

コードにこの奇妙なループがあり、私には理解できませんでした。

それで、私の開発者はそれをグーグルで検索しましたが、私が出会ったすべての記事は、bytes(str).length;Stackoverflowでいくつかの同様のコードを見つけた文字列の長さを見つけるためにこれを行いましたが、内部で何が起こっているのか実際には誰も説明しませんでした。

for(len = 0; i < bytelength; len++) {
            bytes1 b = bytes(s)[i];
            if(b < 0x80) {
                i += 1;
            } else if (b < 0xE0) {
                i += 2;
            } else if (b < 0xF0) {
                i += 3;
            } else if (b < 0xF8) {
                i += 4;
            } else if (b < 0xFC) {
                i += 5;
            } else {
                i += 6;
            }
  }

3時間の自己探求の後、私はそれを自分で理解することができました(少し遅いですが、私はそれをしました)。

だから私はそれを書き留めて、私のようなすべての人々に役立つだろうと思いました(ビット、バイト0️⃣1️⃣の経験はあまりありません)。

では、これをブロック解除/デコードしてみましょう

bytes(str).lengthのしくみ

文字列をバイトに変換するとき、これはSolidityが行うことです。

// if we do bytes("xyz"), solidity converts it as 
xyz -> 78 79 7a // 78=x, 79=y, 7a=z
ABC -> 41 42 43 // 41=A, 42=B, 43=C

注:文字列をバイトに変換するには、このWebサイトを使用してください。

表示されている場合、各文字は1バイトを生成します。そのため、bytes(””)。lengthを実行すると、文字列の長さが取得されます。

ただし、生成されたバイトが複数ある文字がいくつかあります。例えば:

€ -> e2 82 ac

ユーロのシンボルの場合、生成されるバイトは3です。

したがって、ユーロの記号を含む文字列の長さを見つけようとすると、€によって返される長bytes(str).lengthさは、この文字の正しい文字列の長さを返しません。は3バイト生成されます。

そのとき、上で見たforループが助けになります。

このバイト配列を繰り返し処理してe2 82 ac、そのループ内で何が起こっているかを確認しましょう。

for(len = 0; i < bytelength; len++) {
            bytes1 b = bytes(s)[i];
                        // b = e2 for first iteration
            if(b < 0x80) {
                i += 1;
            } else if (b < 0xE0) {
                i += 2;
            } else if (b < 0xF0) {
                i += 3;
            } else if (b < 0xF8) {
                i += 4;
            } else if (b < 0xFC) {
                i += 5;
            } else {
                i += 6;
            }
  }

最初の反復b=e2では、次の行に条件があります。

if(b < 0x80) {
     i += 1;
}

これをデコードしてみましょう。この条件は、基本的にこれらの16進文字の10進値を比較します。

0x80 -> 128
// our b is e2 at the moment, decimal value for e2 = 226
0xe2 -> 226

通常の文字の場合、16進文字の10進変換は< 128、のようにa、97になります。

したがって、次のようにすべての条件を確認すると、次のようになります。

for(len = 0; i < bytelength; len++) {
            bytes1 b = bytes(s)[i];
            if(b < 0x80) { //0x80 = 128 => 226 < 128 ❌
                i += 1;
            } else if (b < 0xE0) { //0xE0 = 224 => 226 < 224 ❌
                i += 2;
            } else if (b < 0xF0) { //0xF0 = 240 => 226 < 240 ✅
                i += 3;
            } 
                        ...
  }

だから、今私たちのi is 3

したがって、forループの条件は、3<3falseになり、ループが中断され、の値は

len will be 1この時点で

以上です。文字列「 €」の長さの正しい値です。

「 € 」のような文字列をさらに試したい場合は、1バイトを超える文字の小さなリストを次に示します。

€ -> e2 82 ac 
à -> c3 83
¢ -> c2 a2

abc¢Ãたとえば、のようなランダムな文字列を作成して、試してみてください。

タダ!そして今、それは機能します。

ソース:https ://betterprogramming.pub/in-the-world-of-javascript-finding-the-length-of-string-is-such-an-easy-thing-just-do-str-length-4b4b33dbed09

#javascript 

What is GEEK

Buddha Community

Solidityで文字列の長さを見つける方法
高橋  花子

高橋 花子

1653303600

Solidityで文字列の長さを見つける方法

Javascriptの世界では、文字列の長さを見つけるのはとても簡単なことでstr.length、それだけです。

しかし、文字列はSolidity内で動作するのにそれほど友好的ではありません。

Solidityでは、文字列は配列内に格納されている文字のグループであり、データをバイト単位で格納します。

文字列型にはlengthメソッドはありません。

Buildspaceのbuild-polygon-ensプロジェクトを実行していて、次のリンクを見つけましたStringUtils.sol

Solidityで文字列の長さを見つける方法を知っていたので、文字列をバイトに変換してその長さを見つけることができます。したがって、実行するのと同じくらい簡単なはずbytes(str).length;ですが、このutilファイルのメソッドは少し異なります。

// SPDX-License-Identifier: MIT
// Source:
// https://github.com/ensdomains/ens-contracts/blob/master/contracts/ethregistrar/StringUtils.sol
pragma solidity >=0.8.4;library StringUtils {
    /**
     * @dev Returns the length of a given string
     *
     * @param s The string to measure the length of
     * @return The length of the input string
     */
    function strlen(string memory s) internal pure returns (uint256) {
        uint256 len;
        uint256 i = 0;
        uint256 bytelength = bytes(s).length;        for (len = 0; i < bytelength; len++) {
            bytes1 b = bytes(s)[i];
            if (b < 0x80) {
                i += 1;
            } else if (b < 0xE0) {
                i += 2;
            } else if (b < 0xF0) {
                i += 3;
            } else if (b < 0xF8) {
                i += 4;
            } else if (b < 0xFC) {
                i += 5;
            } else {
                i += 6;
            }
        }
        return len;
    }
}

コードにこの奇妙なループがあり、私には理解できませんでした。

それで、私の開発者はそれをグーグルで検索しましたが、私が出会ったすべての記事は、bytes(str).length;Stackoverflowでいくつかの同様のコードを見つけた文字列の長さを見つけるためにこれを行いましたが、内部で何が起こっているのか実際には誰も説明しませんでした。

for(len = 0; i < bytelength; len++) {
            bytes1 b = bytes(s)[i];
            if(b < 0x80) {
                i += 1;
            } else if (b < 0xE0) {
                i += 2;
            } else if (b < 0xF0) {
                i += 3;
            } else if (b < 0xF8) {
                i += 4;
            } else if (b < 0xFC) {
                i += 5;
            } else {
                i += 6;
            }
  }

3時間の自己探求の後、私はそれを自分で理解することができました(少し遅いですが、私はそれをしました)。

だから私はそれを書き留めて、私のようなすべての人々に役立つだろうと思いました(ビット、バイト0️⃣1️⃣の経験はあまりありません)。

では、これをブロック解除/デコードしてみましょう

bytes(str).lengthのしくみ

文字列をバイトに変換するとき、これはSolidityが行うことです。

// if we do bytes("xyz"), solidity converts it as 
xyz -> 78 79 7a // 78=x, 79=y, 7a=z
ABC -> 41 42 43 // 41=A, 42=B, 43=C

注:文字列をバイトに変換するには、このWebサイトを使用してください。

表示されている場合、各文字は1バイトを生成します。そのため、bytes(””)。lengthを実行すると、文字列の長さが取得されます。

ただし、生成されたバイトが複数ある文字がいくつかあります。例えば:

€ -> e2 82 ac

ユーロのシンボルの場合、生成されるバイトは3です。

したがって、ユーロの記号を含む文字列の長さを見つけようとすると、€によって返される長bytes(str).lengthさは、この文字の正しい文字列の長さを返しません。は3バイト生成されます。

そのとき、上で見たforループが助けになります。

このバイト配列を繰り返し処理してe2 82 ac、そのループ内で何が起こっているかを確認しましょう。

for(len = 0; i < bytelength; len++) {
            bytes1 b = bytes(s)[i];
                        // b = e2 for first iteration
            if(b < 0x80) {
                i += 1;
            } else if (b < 0xE0) {
                i += 2;
            } else if (b < 0xF0) {
                i += 3;
            } else if (b < 0xF8) {
                i += 4;
            } else if (b < 0xFC) {
                i += 5;
            } else {
                i += 6;
            }
  }

最初の反復b=e2では、次の行に条件があります。

if(b < 0x80) {
     i += 1;
}

これをデコードしてみましょう。この条件は、基本的にこれらの16進文字の10進値を比較します。

0x80 -> 128
// our b is e2 at the moment, decimal value for e2 = 226
0xe2 -> 226

通常の文字の場合、16進文字の10進変換は< 128、のようにa、97になります。

したがって、次のようにすべての条件を確認すると、次のようになります。

for(len = 0; i < bytelength; len++) {
            bytes1 b = bytes(s)[i];
            if(b < 0x80) { //0x80 = 128 => 226 < 128 ❌
                i += 1;
            } else if (b < 0xE0) { //0xE0 = 224 => 226 < 224 ❌
                i += 2;
            } else if (b < 0xF0) { //0xF0 = 240 => 226 < 240 ✅
                i += 3;
            } 
                        ...
  }

だから、今私たちのi is 3

したがって、forループの条件は、3<3falseになり、ループが中断され、の値は

len will be 1この時点で

以上です。文字列「 €」の長さの正しい値です。

「 € 」のような文字列をさらに試したい場合は、1バイトを超える文字の小さなリストを次に示します。

€ -> e2 82 ac 
à -> c3 83
¢ -> c2 a2

abc¢Ãたとえば、のようなランダムな文字列を作成して、試してみてください。

タダ!そして今、それは機能します。

ソース:https ://betterprogramming.pub/in-the-world-of-javascript-finding-the-length-of-string-is-such-an-easy-thing-just-do-str-length-4b4b33dbed09

#javascript