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