interface - marshal - Convertir la interfaz de Golang arbitraria a la matriz de bytes
json to interface golang (1)
Estoy tratando de escribir un hash que acepte todos los tipos de datos. Una vez en la función, manejo los datos como una matriz de bytes. Tengo problemas para averiguar cómo convertir una interface{}
arbitraria interface{}
a una matriz de bytes.
Intenté usar el paquete binario pero parecía depender del tipo de datos pasados. Uno de los parámetros de Write()
fn (docs) requería conocer el orden de bytes del parámetro.
Todos los tamaños de tipos de datos son un múltiplo de un byte (incluso el bool), por lo que esto debería ser simple en teoría.
Código en cuestión abajo,
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
}
Otros problemas en mi código me alejaron del paquete de gob
antes, resulta que fue la forma correcta como sugirió @nvcnvn. Código relevante sobre cómo resolver este problema a continuación:
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
}