固定长度字节数组转化

我们之前也学习了那么多的数组了,那么这些数组类型是否可以相互转换呢?答案是肯定的。

我们先来看看固定长度字节数组各bytes之间是怎么转换的吧~

pragma solidity ^0.4.16;

contract DynamicString{

bytes12 name = 0x7a68656e676a69616e78756e;

function changeBytes1() view returns(bytes1){
return bytes1(name);
}

function changeByte2() view returns(bytes2){
return bytes2(name);
}

function changeByte3() view returns(bytes16){
return bytes16(name);
}
}

编译运行之后,我们查看结果发现:

通学智能合约系列(八)--字节数组转换_区块链

就是说,​​转小从头截取,转大末尾补零​​。

固定长度字节数组转动态字节数组

我们知道了固定长度字节数组之间的转换,那么固定长度字节数组如何转为动态字节数组呢?它来了~~~

对于不太熟悉编程的朋友们,不要害怕,跟着我把这段代码敲出来先。

pragma solidity ^0.4.16;

contract DynamicString{

bytes12 name = 0x7a68656e676a69616e78756e;

function fixBytesToDynamicBytes() view returns(bytes){
//return bytes(name);
bytes memory newName = new bytes(name.length);
for(uint i= 0;i < name.length;i++){
newName[i] = name[i];
}
return newName;
}
}

上述注释部分,我们直接return想直接转成动态字节数组,显然是行不通的。于是,我们采用迂回战术,使用一个for循环来挨个字节进行转换,目的达成。

然后这里,我们要注意两点:

一是局部变量(也就是newName在我们的方法内部,这里需要加memory,先照着写,至于为什么,这里先卖个关子,我们后续会细细介绍。)

二是,for循环的初始化参数,我们使用uint:代表无符号整型。这里有别与其他语言哦。

动态长度字节数组转为string

废话不多说,直接上代码:

pragma solidity ^0.4.16;

contract Bytes2String{

bytes name = new bytes(2);

function init(){
name[0] = 0x7a;
name[1] = 0x68;
}

function bytesToString() view returns(string){
return string(name);
}
}

我们线执行初始化方法、在执行​​bytesToString​​​方法,会展示结果,也就是我们原作者的名字开头​​zh​​。

我们上面都知道了动态长度数组可以强制转换为string,那么固定长度数组可不可以强制转为string呢?

我们编写如下合约:

pragma solidity ^0.4.16;

contract Bytes32ToString{

bytes2 name = 0x7a68;

function bytes32ChangeString() returns(string){
return string(name);
}

}

会发现编译报错,显然不能这么写。

通学智能合约系列(八)--字节数组转换_字节数组_02

那我们该如何操作呢?

从上面的学习中,我们知道。固定长度字节数组可以转为动态字节数组,而动态字节数组可以转为string。所以,这就是我们的思路

请看下面代码:

pragma solidity ^0.4.16;

contract Bytes32ToString{

function byts32ToString(bytes32 inputName) view returns(string){
bytes memory newName = new bytes(inputName.length);
for(uint i = 0;i<newName.length;i++){
newName[i] = inputName[i];
}
return string(newName);
}

}

编译部署后,我们输入​​0x7a68​​​,输出​​zh​​,但是我们会发现后续还跟了很多个零,显然不符合我们的诉求。

如图:

通学智能合约系列(八)--字节数组转换_数组_03

在作者原视频中,详细地介绍了for循环的步骤,鉴于大家都是有经验的开发人员,这里就不做过多介绍了。

那么想要去掉后面的零,该怎么做呢?俗话说的好:遇事不决则判断。我们既然已经知道了结果,那处理起来便很简单了。具体代码如下:

pragma solidity ^0.4.16;

contract Bytes32ToString{

function byts32ToString(bytes32 inputName) view returns(string){

uint count = 0;

for(uint i = 0;i<inputName.length;i++){
if(inputName[i] != 0){
count++;
}
}

bytes memory finalName = new bytes(count);
for(uint j = 0;j<count;j++){
finalName[j] = inputName[j];
}

return string(finalName);

}

}

上述的思路呢,就是我们先去掉输入字节末尾默认追加的零,然后再根据真实长度去拷贝一下我们的字节数组。

如此一来,我们的目的就达成了。

字节数组小节

到这里,字节数组就告一段落啦,我们在此做一个小节.


  • 固定长度字节数组
    • byte1到byte32
  • 动态长度字节数组

    • bytes的初始化–new bytes
    • 获取bytes的长度和内容
    • 修改长度和内容

  • string

    • 不能够直接获取长度和内容
    • 需要转换为bytes获取长度和内容
    • 特殊字符的长度的内容和获取
    • 中文字符占用3个字节

  • 固定长度字节数组之间转换
    • 转小从头截取,转大末尾补零
  • 固定长度转动态长度字节数组
    • 利用new bytes(),然后循环转换。
  • 动态长度字节数组转string
    • 强制转换string();
  • 固定长度字节数组转string
    • 先获取输入字节数组长度,然后再转动态长度字节数组,在强制转换为string();