将简单的哈希函数从c转换为go

时间:2018-08-19 13:07:36

标签: c go hash

我正在尝试将简单的哈希函数从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)

2 个答案:

答案 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位,则可以改用uint16sum += 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)。