1653303600
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️⃣の経験はあまりありません)。
では、これをブロック解除/デコードしてみましょう
文字列をバイトに変換するとき、これは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<3
falseになり、ループが中断され、の値は
len will be 1
この時点で
以上です。文字列「 €」の長さの正しい値です。
「 € 」のような文字列をさらに試したい場合は、1バイトを超える文字の小さなリストを次に示します。
€ -> e2 82 ac
à -> c3 83
¢ -> c2 a2
abc¢Ã
たとえば、のようなランダムな文字列を作成して、試してみてください。
タダ!そして今、それは機能します。
1653303600
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️⃣の経験はあまりありません)。
では、これをブロック解除/デコードしてみましょう
文字列をバイトに変換するとき、これは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<3
falseになり、ループが中断され、の値は
len will be 1
この時点で
以上です。文字列「 €」の長さの正しい値です。
「 € 」のような文字列をさらに試したい場合は、1バイトを超える文字の小さなリストを次に示します。
€ -> e2 82 ac
à -> c3 83
¢ -> c2 a2
abc¢Ã
たとえば、のようなランダムな文字列を作成して、試してみてください。
タダ!そして今、それは機能します。