<p>To calculate the hashes of 'hello space' and 'hello world' without processing 'hello ' twice, in python I write:</p>
<pre><code>>>> a = hashlib.sha1()
>>> a.update('hello ')
>>> b = a.copy()
>>> a.update('space')
>>> b.update('world')
>>> a.hexdigest(), b.hexdigest()
('0db22b798fcb792be5fed7ef8c105cc1ed75f540', '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed')
</code></pre>
<p>(yes, I understand about block sizes; assume 'hello ' is many, many blocks in length.)</p>
<p>My attempt at a golang-equivalent:</p>
<pre><code>var a = sha1.New()
a.Write([]byte("hello "))
var b = a // want a deep copy here
a.Write([]byte("space"))
b.Write([]byte("world"))
var ha = a.Sum(nil)
var hb = b.Sum(nil)
fmt.Println(hex.EncodeToString(ha))
fmt.Println(hex.EncodeToString(hb))
</code></pre>
<p>So: how do I deep-copy a hash.Hash?</p>
<p>edit: reword problem; I want to calculate lots of different hashes with the same prefix.</p>
<hr/>**评论:**<br/><br/>dgryski: <pre><p>No way to do it in general. Probably something hacky with unsafe and reflection. However for sha1, <a href="https://github.com/TvdW/gotor/tree/master/sha1">https://github.com/TvdW/gotor/tree/master/sha1</a></p></pre>tv64738: <pre><p>You can't just deep-copy arbitrary things and expect them to work right. Making a copy is not part of the hash.Hash interface, and not all hash functions expose a mechanism to copy the internal state.</p></pre>TheMerovius: <pre><p>My best answer would be:
<a href="http://play.golang.org/p/zfrGu4mrIU" rel="nofollow">http://play.golang.org/p/zfrGu4mrIU</a></p>
<p>[edit] hm, that doesn't really address the issue. So no, I don't think that's possible at all in go currently.</p></pre>bradfitz: <pre><p>This isn't possible with the standard library. </p></pre>gohacker: <pre><p>O RLY?</p>
<pre><code>func copyHash(src hash.Hash) hash.Hash {
typ := reflect.TypeOf(src)
val := reflect.ValueOf(src)
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
val = val.Elem()
}
elem := reflect.New(typ).Elem()
elem.Set(val)
return elem.Addr().Interface().(hash.Hash)
}
</code></pre></pre>bradfitz: <pre><p>My answer was short for:</p>
<p>This isn't possible with the standard library in a way that is supported, easy, clear, and non-disgusting. :)</p></pre>szabba: <pre><p>At least they wrapped it with a sensibly-typed funcion. ;)</p></pre>dgryski: <pre><p>Yoinked for later </p></pre>gsscoder: <pre><p>May this package can help you: <a href="https://godoc.org/code.google.com/p/rog-go/exp/deepcopy" rel="nofollow">https://godoc.org/code.google.com/p/rog-go/exp/deepcopy</a> ?</p></pre>stevvooe: <pre><p>We created a <a href="http://godoc.org/github.com/stevvooe/resumable" rel="nofollow">resumable hash package</a> for doing this type of operation. Just side-effect import the resumable version of the package and instantiate through standard <code>crypto.SHA256.New()</code>. That instance will be a <code>hash.Hash</code> and can be used as such anywhere. When you need to save the state, just type assert to <code>resumable.Hash</code> and use <code>(resumable.Hash).Save</code> and <code>(resumable.Hash).Restore</code> to accomplish your goal.</p>
<p>Note this is more for state serialization rather than deep copy. We could add that, if desired, since deep copy is a very similar operation.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传