2014-04-11 9 views
17

पर मनमाने ढंग से गोलांग इंटरफ़ेस को कनवर्ट करें मैं एक हैश लिखने की कोशिश कर रहा हूं जो सभी डेटाटाइप स्वीकार करेगा। एक बार फ़ंक्शन में, मैं डेटा को बाइट सरणी के रूप में संभालता हूं। मुझे एक बाइट सरणी में मनमाने ढंग से interface{} डालने का तरीका समझने में परेशानी हो रही है।बाइट सरणी

मैंने बाइनरी पैकेज का उपयोग करने की कोशिश की लेकिन यह पारित डेटा के प्रकार पर निर्भर करता है। Write() fn (docs) के पैरामीटर में से एक पैरामीटर के बाइट ऑर्डर को जानने की आवश्यकता है।

सभी डेटाटाइप आकार बाइट (यहां तक ​​कि बूल) के कुछ बहु हैं, इसलिए यह सिद्धांत में सरल होना चाहिए।

नीचे दिए गए प्रश्न में

संहिता,

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 
} 
+3

पीकेजी "एन्कोडिंग/गोब" के बारे में कैसे? क्या आप इसका इस्तेमाल कर सकते हैं? – nvcnvn

+0

@nvcnvn, काम कर रहा प्रतीत होता है। मैंने पहले कोशिश की लेकिन अब मुझे एहसास है कि छोटे मूल्यों पर हैश में कमजोरी है (0-62 समान हैं?)। मैंने उस सीमा को बदल दिया जो मैं काम कर रहा था अब यह काम करता है। धन्यवाद! –

+0

हैश एफएन में त्रुटियों को ठीक किया गया, अद्यतन कोड यहां मिला: https://gist.github.com/natebrennand/10442587 –

उत्तर

40

मेरी कोड में अन्य समस्याओं मुझे 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 
} 
+0

अपने प्रश्न के उत्तर के रूप में अपना उत्तर स्वीकार करने के लिए स्वतंत्र महसूस करें :) – photoionized

+0

यह एक और इसके विपरीत: https://play.golang.org/p/mJPMN1_KSv – sromku

+1

इस विधि के उपयोग को दिखाते हुए एक उदाहरण होना अच्छा लगेगा। गो के साथ मेरे जैसे कई शुरुआती लोगों के लिए, यह वास्तव में आवंटित करने में मदद करेगा! –