Solidity两个string的比较
有三种比较方法
方法一:比较string的哈希值
方法二:先比较string的长度,再比较每个对应位置的字母是否相同
方法三:先比较string的长度,再比较string的哈希值
一.比较string的哈希值
function hashCompareInternal(string a, string b) internal returns (bool) {
return keccak256(a) == keccak256(b);
}
二.先比较string的长度,再比较每个对应位置的字母是否相同
function utilCompareInternal(string a, string b) internal returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
}
for (uint i = 0; i < bytes(a).length; i ++) {
if(bytes(a)[i] != bytes(b)[i]) {
return false;
}
}
return true;
}
三.先比较string的长度,再比较string的哈希值
function hashCompareWithLengthCheckInternal(string a, string b) internal returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
} else {
return keccak256(a) == keccak256(b);
}
}
四.三种比较方法的gas分析
在remix上执行也可以看到gas情况,但感觉不准,这里的统计参考:https://blog.csdn.net/xiaomei1xiake2/article/details/81868317
由以上的测试可知:
1.当超过两个字母需要比较的时候,哈希方法(方法一和方法三)消耗的gas比较少;
2.当这两个string的长度不同时,先进行长度比较(方法二和方法三)可以节省将近40%的gas。
3.先进行长度比较只是多花了3%的gas,但可能可以节省40%的gas。
4.与使用字母比较(方法二)的方法相比,使用哈希方法(方法一和方法三)gas的消耗比较稳定。使用字母比较的方法消耗gas的数量呈线性增长。
五.在实际应用中,可以AOP方式,也可以在函数中直接判断
pragma solidity ^0.4.24; contract StringComp { mapping (address => bool) public compareRecord; bool public checkResult = false; modifier check(string _str1,string _str2) {
require(keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_str2)));
_;
} // 使用AOP方式check比较两个字符串
function func1 (string __str1, string __str2) public check(__str1,__str2) returns(bool) {
// 保存调用者的比较结果
compareRecord[msg.sender] = true;
} // 函数中直接判断
function compareStr (string _str1, string _str2) public returns(bool) {
if(keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_str2))) {
// 如果二者相等,使checkResult为true
checkResult = true;
}else {
checkResult = false;
}
// 返回checkResult
return checkResult;
}
}
在这里,有直接用abi.encodePacked进行打包,关于abi.encodePacked方法说明,详见如下:
详见:https://solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html
五.特别说明
keccak256方法在0.4.2及其下版本不支持,至少需0.4.3版本。
附:在remix上运行截图
1.StrComp.sol
pragma solidity ^0.4.24; contract StrComp { function hashCompareInternal(string a, string b) public returns (bool) {
return keccak256(a) == keccak256(b);
} function utilCompareInternal(string a, string b) public returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
}
for (uint i = 0; i < bytes(a).length; i ++) {
if(bytes(a)[i] != bytes(b)[i]) {
return false;
}
}
return true;
} function hashCompareWithLengthCheckInternal(string a, string b) public returns (bool) {
if (bytes(a).length != bytes(b).length) {
return false;
} else {
return keccak256(a) == keccak256(b);
}
}
}
2.StringComp.sol
pragma solidity ^0.4.24; contract StringComp { mapping (address => bool) public compareRecord; bool public checkResult = false; modifier check(string _str1,string _str2) {
require(keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_str2)));
_;
} // 使用AOP方式check比较两个字符串
function func1 (string __str1, string __str2) public check(__str1,__str2) returns(bool) {
// 保存调用者的比较结果
compareRecord[msg.sender] = true;
} // 函数中直接判断
function compareStr (string _str1, string _str2) public returns(bool) {
if(keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_str2))) {
// 如果二者相等,使checkResult为true
checkResult = true;
}else {
checkResult = false;
}
// 返回checkResult
return checkResult;
}
}
参考文章:https://blog.csdn.net/xiaomei1xiake2/article/details/81868317
https://www.liankexing.com/index.php/Question/question_page.html?id=1249
https://solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html
remix地址:https://remix.ethereum.org/
Solidity两个string的比较的更多相关文章
- 取两个String数组的交集
import org.testng.annotations.Test; import java.util.HashMap; import java.util.LinkedList; import ja ...
- js比较两个String字符串找出不同,并将不同处高亮显示
根据java代码改写成js,下边js文件代码: function StringBuffer() { this.__strings__ = []; }; StringBuffer.prototype.a ...
- 对比两个String无规律包含连续4个相同字符返回true的方法
package com.qif.dsa.util; import java.util.ArrayList; import java.util.List; /** * @author * @Title: ...
- 如何判断两个String是否是Anagrams_java实现
Anagrams:是颠倒字母顺序的字符串 本文提供三个方法,分别分析时间空间复杂度 方法一:暴力遍历 时间复杂度:O(n^2) 方法二:基于排序算法,Sorting的时间复杂度是O(n*log(n)) ...
- 两个string数组对应比较
最近做的array string类型对比.这个可能比较复杂,用的是linq 是请教别人的,我在这里记录一下 jquery 方法里面的数组 function arrtxt() { var arrt= [ ...
- c++实现一个比较两个string类型的版本号的小demo
在软件实现更新模块的时候,有可能会判断一下服务器上的版本的版本号和本地版本的版本号. 下面有类似这样形式的版本号:string str = "0.0.0.1"; 分析一下可以看出, ...
- 计算两个String 类型的时间相关几个月
/** * 返回两个时间段相隔几个月 * @param date1 * @param date2 * @return * @throws ParseException * @throws ParseE ...
- 找两个string[ ]里不同的元素
方法 1:string[] strListOne = new string[] {"Type", "Parent Id","Status"} ...
- Java实现交换两个String
在Java中我们所使用的实例变量其实都是一个引用,所以如果要求实现一个swap(String A, String B)这种函数时无法实现的,因为在类方法的定义中是先对行参进行地址传递,然后对形参修改, ...
随机推荐
- 用 PHP 编写 http 服务器
概述 众所周知,我们一般使用 PHP 开发Web程序时需要使用到比如Apache或Nginx等Web服务器来支持,那么有没有办法直接使用PHP开发HTTP服务器,答案当然是可以的,最近看了一遍Work ...
- delphi_xe开发ios环境的安装与设置
http://wenku.baidu.com/link?url=NE3xJOZiLppdxCbXJX3W0vyLHv6uA_U8uamjx9NJIIcxnfuC2P9eWx3d6Xwco-ugS8G ...
- musql 添加字段语句
修改表tax_version添加up_content属性为text类型非空,注释为“更新内容”,字段添加再“name”属性后面 ALTER TABLE `tax_version` ADD `up_co ...
- S11 day 95 RestFramework 之 视图
1. 基于APIVIEW视图序列化 我们会发现两个类有好多重复的代码.所以我们引入了GenericAPIView (继承了APIView) 2.Generic ApiVIew和 ListModel ...
- Day 35 验证客户端的合法性+socketserver
一 .getpeername和getsoketopt的用法 服务器端代码 import socket sk =socket.socket() sk.bind(('127.0.0.1',9000)) s ...
- OSX - libc++究竟是啥?
libc++是什么? libc++是C++标准库的实现! libc++ is an implementation of the C++ standard library, targeting C++ ...
- SecureCRT连接Ubuntu,centos失败解决
SecureCRT连接Ubuntu,centos失败,长时间的重新连接,连接不了. Ubuntu,centos默认未安装ssh远程加密连接服务.使用命令,安装即可. 1.sudo apt-get in ...
- 彻底弄懂css3的flex弹性盒模型
由于在日常工作中使用css或者bootstrap的栅格系统已经能很好的满足业务需求,所以一直以来对css3的弹性布局不是很感冒. 近日有幸在一篇文章中领略了flex的魅力--简洁优雅.随试之. /*容 ...
- 归并排序的理解和实现(Java)
归并排序介绍 归并排序(Merge Sort)就是利用归并的思想实现的排序方法.它的原理是假设初始序列含有fn个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n2\fr ...
- celery问题记录
1. 问题:WARNING/MainProcess] /home/jihonghe/.virtualenvs/py3_dj217_env/lib/python3.6/site-packages/bil ...