gohashsha1

Correct way to parse X bytes in GoLang


I am misunderstanding bytes and reading them when representing hexadecimal

The example is the following: I receive a response of the following format:
"795ea8776befc95ea2becd8020c7a284677b4161 some/other/text\n"

As you can see it's a SHA-1, which is stored as 20 bytes. My assumption was you could just do:

res := []byte("795ea8776befc95ea2becd8020c7a284677b4161 some/other/text\n")
hash := res[:20]
fmt.Println(hash)

However this doesn't work. It only grabs the first 20 characters of the hexadecimal format, as opposed to the full 40 characters. I believe this is to do with the fact that go may use more than 1 byte per character? If so, what is the correct approach for parsing a response when you know you need X bytes.

I know the simple answer to the example given would be to just split on space and then grab the first element from the split array, but I want to understand grabbing X bytes. It could be there's no space, or it could be I want the [5:25] bytes of a string. What is the idiomatic Go way?


Solution

  • You have a hex digest, which is like a text-encoded (ASCII) representation of the bytes. It's twice as long. If you want the underlying bytes, you'd need to decode the digest from a string:

    package main
    
    import (
        "encoding/hex"
        "fmt"
    )
    
    func main() {
        res := []byte("795ea8776befc95ea2becd8020c7a284677b4161 some/other/text\n")
        hashDigest := string(res[:40])
        hash, err := hex.DecodeString(hashDigest)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(hash)
    }
    

    If you have the digest in a byte array in the first place, and not a string, then you may be able to use hex.Decode instead.