You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Golang中实现与Kotlin一致的字符串哈希逻辑?

问题:Kotlin与Golang字符串哈希结果不一致的原因?

在服务A中,我使用如下Kotlin代码对字符串进行哈希处理:

fun String.toHash(): Long {
    var hashCode = this.hashCode().toLong()
    if (hashCode < 0L) {
        hashCode *= -1
    }
    return hashCode
}

我希望在服务B的Golang代码中复现该逻辑,以保证相同字符串得到完全一致的哈希值。我误以为Kotlin的哈希返回64位整数,因此编写了如下Golang代码:

func hash(s string) int64 {
    h := fnv.New64()
    h.Write([]byte(s))
    v := h.Sum64()
    return int64(v)
}

但单元测试时结果不一致,测试代码如下:

func Test_hash(t *testing.T) {
    tests := []struct {
        input  string
        output int64
    }{
        {input: "papafritas", output: 1079370635},
    }
    for _, test := range tests {
        got := hash(test.input)
        assert.Equal(t, test.output, got)
    }
}

测试得到的结果为:7841672725449611742,与预期的1079370635不符,请问哪里出错了?


问题根源与解决方案

核心错误

你用错了哈希算法。Kotlin的String.hashCode()继承自Java的String.hashCode(),它是一个32位的哈希算法,并非FNV-64。你在Golang中误用了FNV-64哈希,自然会得到完全不同的结果。

Java/Kotlin String哈希规则

Java/Kotlin的字符串哈希计算逻辑是:

  • 初始值 h = 0
  • 遍历字符串每个字符 char c:h = 31 * h + c
  • 最终返回32位整数结果(可能为负)

你的Kotlin代码只是把这个32位哈希转成64位长整数,再取绝对值。

正确的Golang实现

按照上述规则,在Golang中复现该逻辑:

func hash(s string) int64 {
    h := int32(0)
    for _, c := range s {
        h = 31*h + int32(c)
    }
    // 转成int64并取绝对值
    res := int64(h)
    if res < 0 {
        res = -res
    }
    return res
}

验证测试用例

用这个实现测试"papafritas":

  • 计算得到的32位哈希是1079370635(正数),转成int64后取绝对值还是1079370635,与预期结果完全一致。

内容的提问来源于stack exchange,提问作者Matias Barrios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 19:45:21