drouie2014 2017-09-21 12:59
浏览 125

如何在Go中将数组段转换为数组?

I'm using the hash function sha256.Sum256(data []byte) [sha256.Size]byte. I need that the returned digest is stored at the end of another bigger array.

var x [sha256.BlockSize+sha256.Size]byte 
? = sha256.Sum256(data)

The only solution I found so far is the following:

var x [sha256.BlockSize+sha256.Size]byte 
var d = sha256.Sum256(data)
copy(x[sha256.BlockSize:], d[:]) 

Is it possible to avoid this copy ?

  • 写回答

1条回答 默认 最新

  • dongsashe6006 2017-09-21 13:07
    关注

    You can avoid the copy if you abandon using the sha256.Sum256() function, and you first create a hash.Hash by calling sha256.New().

    Using a hash.Hash you can calculate the digest using the Hash.Sum() method, and what's important here is that you can pass a slice to it indicating that you want the results to be appended to that.

    For the target slice, you can pass a slice value pointing to the element in your x array where you want the result, e.g. with 0 length (as result will be appended to this slice, not filled into it):

    var x [sha256.BlockSize+sha256.Size]byte
    h := sha256.New()
    h.Write(data)
    h.Sum(x[sha256.BlockSize:sha256.BlockSize])
    

    See this example to demonstrate it:

    data := []byte("hello")
    fmt.Println(sha256.Sum256(data))
    
    var x [sha256.BlockSize + sha256.Size]byte
    h := sha256.New()
    h.Write(data)
    res := h.Sum(x[sha256.BlockSize:sha256.BlockSize])
    fmt.Println(res)
    fmt.Println(x)
    

    First I print the result using sha256.Sum256() so we have an "authentic" result to comapre to. Then I call and print the result of Hash.Sum(). Last we print the x array to verify the result is in it.

    Output (try it on the Go Playground):

    [44 242 77 186 95 176 163 14 38 232 59 42 197 185 226 158 27 22 30 92 31 167 66 94 115 4 51 98 147 139 152 36] [44 242 77 186 95 176 163 14 38 232 59 42 197 185 226 158 27 22 30 92 31 167 66 94 115 4 51 98 147 139 152 36] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 44 242 77 186 95 176 163 14 38 232 59 42 197 185 226 158 27 22 30 92 31 167 66 94 115 4 51 98 147 139 152 36]

    Update:

    You wrote that you knew about this but intentionally avoided this to avoid allocating a hash.Hash. Know that sha256.Sum256() uses the same implementation that is returned by sha256.New() under the hood, so this solution is most likely not slower (did not benchmark). Also you can reuse the hasher! So in fact this can be made faster. To reuse, call the Hash.Reset() method.

    Update #2:

    You indicated you have to do this in every web request. In this case probably using sha256.Sum256() is the best choice. If you do need to boost performance, you could opt to "clone" the sha256 package, and in your cloned version you could modify the Sum256() function to receive a slice where the results could be stored directly (my linked other answer shows the first step toward this), but seriously, copying 32 bytes (size of SHA-256 digest) is so fast, not worth the hassle, and performance gain would not be huge.

    See related question: How to efficiently hash (SHA 256) in golang data where only the last few bytes changes

    评论

报告相同问题?

悬赏问题

  • ¥15 安装svn网络有问题怎么办
  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献