Video Coming Soon...
37: sha2sum
There's many different hashing utilities, but they all do the same thing: convert a gigantic number to a smaller number using cryptographic primitives. The one you'll use is called sha512 and Go provides very good cryptography support in the standard library.
The way a tool like sh2sum works is this:
- It opens a file and reads in the bytes.
- Each byte is also a number, so it can feed that byte to a cryptographic function.
- This function's design allows it to input many, many numbers but only output one large number. In our case, a 512 bit number.
- These functions are required to have "no collisions," which means if you feed them even slightly different inputs you should get totally different results.
- This lets you
sha2suma file to confirm that you received the right one, that it wasn't corrupted, and to just know if two files are actually different.
The Challenge
Since it's important that you use the correct function, you'll be required to use crypto/sha512 for your sha2sum implementation. After you get that working you should implement as many of the GNU options as possible.
Requirements
The only new package is the crypto/sha512 that I mentioned earlier:
See the list of requirements
- fmt -- https://pkg.go.dev/fmt
- flag -- https://pkg.go.dev/flag
- os -- https://pkg.go.dev/os
- log -- https://pkg.go.dev/log
- crypto/sha512 -- https://pkg.go.dev/crypto/sha512
Spoilers
Before you peek, try using fmt.Sprint("%x", b) to get that style of output you see sha2sum do. This is called hexadecimal format.
See my first version code
View Source file go-coreutils/sha512sum/main.go Onlypackage main
import (
"fmt"
"flag"
"os"
"log"
"crypto/sha512"
)
type Opts struct {
Inputs []string
}
func ParseOpts() Opts {
var opts Opts
flag.Parse()
opts.Inputs = flag.Args()
return opts
}
func ToHex(hash [sha512.Size]byte) string {
result := ""
for _, b := range hash {
result += fmt.Sprintf("%x", b)
}
return result
}
func main() {
opts := ParseOpts()
for _, fname := range opts.Inputs {
in_data, err := os.ReadFile(fname)
if err != nil { log.Fatal(err) }
hash := sha512.Sum512(in_data)
fmt.Println(ToHex(hash), fname)
}
}
Testing It
If you want to push your learning further then you can try to implement an automated test for this. I actually need to learn how to test utilities like this with Go, so for now just consider this an extra challenge for later until I learn how to teach it.
Register for Learn Go the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.