cpp和golang关于某个函数的对比

# 背景

最近在工作中遇到了一个问题,过去的服务大都是cpp,现在需要迁移到golang,其中涉及到了相关函数,本来是很简单的一个函数,但是这其中却踩了一些坑,下面记录下遇到的问题。

# 问题

cpp函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
string methed1(string src)
{
    char str[] = "0123456789ABCDEF";
    char* des = (char*)malloc(src.size()*2+1);
    int i=0;
    for(;i<src.size();i++) {
        des[i*2]   = str[src[i]>>4];
        des[i*2+1] = str[src[i]&0x0f];
    }
    des[i*2] = 0;
    string out = des;
    free(des);
    return out;
}

因为有的地方会用到这个函数,所以也需要钱已到golang服务中。golang代码如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
func methed2(src string) string {
	srcBytes := []byte(src)
	str := []byte("0123456789ABCDEF")
	des := make([]byte, len(srcBytes)*2+1)
	i := 0
	for ; i < len(srcBytes); i++ {
		des[i*2] = str[srcBytes[i]>>4]
		des[i*2+1] = str[srcBytes[i]&0x0f]
	}
	des[i*2] = 0
	return string(des)
}

正常来看这个代码逻辑是没有问题的,但是当开始测试的时候遇到麻烦了,在网络传输中发现了不可预知的报错。

# 解决

自测时,是将这两个函数打印到控制台做的对比,发现内容是一样的。于是再次确认了一下,打印结果相同。这里便陷入了坑了,拿着错误信息,找到了错误原因:

cpp字符串是是以“\0”结尾的,对应的ASCII码为0,这也是cpp代码为什么最后要多一个0的原因,但是golang并没有这样的约定,所以并不需要。

最终代码如下,解决了这个问题。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func methed2(src string) string {
	srcBytes := []byte(src)
	str := []byte("0123456789ABCDEF")
	des := make([]byte, len(srcBytes)*2)
	i := 0
	for ; i < len(srcBytes); i++ {
		des[i*2] = str[srcBytes[i]>>4]
		des[i*2+1] = str[srcBytes[i]&0x0f]
	}
	return string(des)
}
Licensed under CC BY-NC-SA 4.0