我正在尝试将简单的哈希函数从C转换为Go。
这些C和Go脚本之间有什么区别?如何修复Go代码?
C->结果为{FB; 01; 4C | 64:KDY; KMT; KYR; KT0; TKK; PAC; UD01; UD02; UD03; ID01; ID02; ID03; SYS | 124A}
int sum;
char* pChar;
char s[8];
msg = "{FB;01;4C|64:KDY;KMT;KYR;KT0;TKK;PAC;UD01;UD02;UD03;ID01;ID02;ID03;SYS|"
sum = 0;
pChar = msg + 1; // sum starts after the opening {
while (*pChar != 0) {
sum += (int)*pChar++;
}
sprintf(s, "%04X}", sum);
strcat(msg, s);
Go->结果为{FB; 01; 4C | 64:KDY; KMT; KYR; KT0; TKK; PAC; UD01; UD02; UD03; ID01; ID02; ID03; SYS | 004A}
msg := "{FB;01;4C|64:KDY;KMT;KYR;KT0;TKK;PAC;UD01;UD02;UD03;ID01;ID02;ID03;SYS|"
var sum uint8
for i := 1; i < len(msg); i++ {
sum += msg[i]
}
s := fmt.Sprintf("%04X}", sum)
req := strings.Join([]string{msg, s}, "")
fmt.Println(req)
答案 0 :(得分:4)
您需要将“ var sum”设为“ uint16”,否则它将永远不会超过00FF。
答案 1 :(得分:2)
在您的C代码中,sum
的类型为int
,这是一个有符号整数类型,大小至少为16位 1 。
但是,在您的Go代码中,sum
的类型为uint8
,这是一种无符号整数类型,限制为8位。
从格式字符串%04X}
来看,您可能想要一个16位值。
要修复Go代码,只需将uint8
更改为int
,然后使用sum += int(msg[i])
使编译器满意。如果要将sum
的值严格保留16位,则可以改用uint16
和sum += uint16(msg[i])
。
如果您想知道为什么需要将msg[i]
包装在uint16(...)
中,这是因为要将值转换为其他类型。 C具有“整数提升”规则,该规则自动将宽度小于int
的值转换为类型int
的值。但是,Go没有这样的规则,只是拒绝编译,指出类型不兼容。
顺便说一下,由于它具有自动内存管理功能,您可以在Go代码中简单地做到这一点:
req := msg + fmt.Sprintf("%04X}", sum)
fmt.Println(req)
甚至:
s := fmt.Sprintf("%04X}", sum)
fmt.Println(msg + sum)
您当前的方法没有错;只是太冗长了。
1 int
在C语言中必须至少为16位,在Go语言中至少必须为32位,但是如今这两种语言通常都为32位。但是,您应该知道,在某些当前系统上,它可能是64位的,并且在将来的某个时候,对于任何一种语言,默认情况下,它很可能默认为64位。他们不需要保持数据类型大小同步。在添加msg
中的值时,请记住这一点,以确保sum
的值是16位(或仅使用uint16
)。