interface - 将任意 Golang 接口(interface)转换为字节数组

标签 interface go bytearray

我正在尝试编写一个可以接受所有数据类型的哈希。进入函数后,我将数据作为字节数组处理。我无法弄清楚如何将任意 interface{} 转换为字节数组。

我尝试使用二进制包,但它似乎取决于传入的数据类型。Write() fn (docs) 的参数之一需要知道参数的字节顺序。

所有数据类型的大小都是字节的倍数(甚至是 bool 值),所以理论上应该很简单。

下面有问题的代码,

package bloom

import (
    "encoding/gob"
    "bytes"
)

// adapted from http://bretmulvey.com/hash/7.html
func ComputeHash(key interface{}) (uint, error) {
    var buf bytes.Buffer
    enc := gob.NewEncoder(&buf)
    err := enc.Encode(key)
    if err != nil {
        return 0, err
    }
    data := buf.Bytes()

    var a, b, c uint
    a, b = 0x9e3779b9, 0x9e3779b9
    c = 0;
    i := 0;

    for i = 0; i < len(data)-12; {
        a += uint(data[i+1] | data[i+2] << 8 | data[i+3] << 16 | data[i+4] << 24)
        i += 4
        b += uint(data[i+1] | data[i+2] << 8 | data[i+3] << 16 | data[i+4] << 24)
        i += 4
        c += uint(data[i+1] | data[i+2] << 8 | data[i+3] << 16 | data[i+4] << 24)

        a, b, c = mix(a, b, c);
    }

    c += uint(len(data))

    if i < len(data) {
        a += uint(data[i])
        i++
    }
    if i < len(data) {
        a += uint(data[i] << 8)
        i++
    }
    if i < len(data) {
        a += uint(data[i] << 16)
        i++
    }
    if i < len(data) {
        a += uint(data[i] << 24)
        i++
    }


    if i < len(data) {
        b += uint(data[i])
        i++
    }
    if i < len(data) {
        b += uint(data[i] << 8)
        i++
    }
    if i < len(data) {
        b += uint(data[i] << 16)
        i++
    }
    if i < len(data) {
        b += uint(data[i] << 24)
        i++
    }

    if i < len(data) {
        c += uint(data[i] << 8)
        i++
    }
    if i < len(data) {
        c += uint(data[i] << 16)
        i++
    }
    if i < len(data) {
        c += uint(data[i] << 24)
        i++
    }

    a, b, c = mix(a, b, c)
    return c, nil
}

func mix(a, b, c uint) (uint, uint, uint){
    a -= b; a -= c; a ^= (c>>13);
    b -= c; b -= a; b ^= (a<<8);
    c -= a; c -= b; c ^= (b>>13);
    a -= b; a -= c; a ^= (c>>12);
    b -= c; b -= a; b ^= (a<<16);
    c -= a; c -= b; c ^= (b>>5);
    a -= b; a -= c; a ^= (c>>3);
    b -= c; b -= a; b ^= (a<<10);
    c -= a; c -= b; c ^= (b>>15);

    return a, b, c
}

最佳答案

我的代码中的其他问题导致我早先离开了 gob 包,结果证明这是@nvcnvn 建议的正确方法。下面是如何解决这个问题的相关代码:

package bloom

import (
    "encoding/gob"
    "bytes"
)

func GetBytes(key interface{}) ([]byte, error) {
    var buf bytes.Buffer
    enc := gob.NewEncoder(&buf)
    err := enc.Encode(key)
    if err != nil {
        return nil, err
    }
    return buf.Bytes(), nil
}

关于interface - 将任意 Golang 接口(interface)转换为字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23003793/

相关文章:

java - 定义API时应该返回CompletableFuture还是Future?

go - 在其他程序包中初始化并调用struct时,是否可能仅返回一个字段?

arrays - 在 golang 中使用 neast 和数组创建高级结构

java - Java String.getBytes() 和 Python string -> bytes 之间的行为完全相同吗?

java - 将 byte[] 转换为 String,然后再转换回 byte[]

java - 序列化接口(interface)列表 GSON

c# - 使用通用接口(interface)约束时的协变/逆变难题

vba - 在大型项目上使用接口(interface)时出现错误

pointers - slice 结构行为

performance - 两个 Byte[Array] 的高效按位或