Learn Go by creating a tool — Part 1

In this series of articles we will learn how to create a tool in Go, by following this tutorial will not learn you Go from zero, nor will…

Learn Go by creating a tool — Part 1
Photo by The Lucky Neko on Unsplash

In this series of articles we will learn how to create a tool in Go, by following this tutorial will not learn you Go from zero, nor will learn you everything but should make you feel comfortable start using Go to solve a problem, lets start!.

Calculating MD5 hash of a file

The tool purpose will be to calculate the MD5 hash of of a file in a very similar way like the md5sum command we can find in many OSes like Linux and Macos, an MD5 hash is an one way function that turns any input to to a fixed 128-bit fingerprint.

How the tool will work

We will create many revisions of the tool, each revision will be more complex than the previous and with more features, our first version of the tool will have the sole purpose of reading a file and calculating its MD5 hash.

The code

Here is the code for our first version, we will explain how it works line by line

package main 
 
import ( 
        "crypto/md5" 
        "fmt" 
        "os" 
        "io" 
) 
 
func main() { 
 
        if len(os.Args) < 2 { 
                fmt.Println("Usage md5sum <file>") 
                return 
        } 
 
        filename := os.Args[1] 
 
        file, err := os.Open(filename) 
        defer file.Close() 
        if err != nil { 
            fmt.Println(err) 
            return 
        } 
 
        hash := md5.New() 
        if _,err := io.Copy(hash, file); err != nil { 
            fmt.Println(err) 
            return 
        } 
 
        sum := hash.Sum(nil) 
        fmt.Printf("MD5 (%s) = %x\n",filename,sum)

What package main does

package main marks the file as the entry point file for your program, the compiler will then look for a function called function main() {...}

What import does

import is used to specify the libraries that will be used from our program

What func main does

It is the first function that will be executed, it is the entrypoint of our program

Counting number of arguments

This if statement counts the number of arguments given from the command line, if the number is less than 2 (the program filename and the file that we want to calculate its md5 hash) will return from the main function and exit to the system.

if len(os.Args) < 2 { 
    fmt.Println("Usage md5sum <file>") 
    return 
}

Opening the file to read

Next we want to open the file to read it

filename := os.Args[1] 
file, err := os.Open(filename) 
         
if err != nil { 
    fmt.Println(err) 
    return 
} 
 
defer file.Close()

The filename variable will contain the second command line argument, the filename we want to calculate the md5 hash.

os.Open(filename) tries to open the file, os.Open(..) returns a pointer to the file named fileand and err , if err has content (err != nil) means that there was an error and file is not valid.

defer file.Close() instructs go to close the file as last thing to do before program exits and only if the file has been opened successfully.

Calculating the hash

This part of code calculates the md5 hash of the file

hash := md5.New() 
 
if _,err := io.Copy(hash, file); err != nil { 
    fmt.Println(err) 
    return 
 } 
 
 sum := hash.Sum(nil) 
 fmt.Printf("MD5 (%s) = %x\n",filename,sum)

hash := md5.New() this returns a struct pointer with callable functions, will be used to to calculations.

io.Copy(hash, file) streams file bytes to hash.

sum := hash.Sum(nil) calculates the md5 hash, nil is needed to perform plain calculation of md5

fmt.Printf(“MD5 (%s) = %x\n”,filename,sum) prints the filename and the hash value in hex.

How to compile and run the program

i have named my program as md5sum.go to compile it enter

go build md5sum.go

if nothing goes wrong you should see an executable in the same folder

Running the program

To run the compiled program enter the following, this will calculate the md5 hash of your source code.

md5sum md5sum.go 
MD5 (md5sum.go) = df57ba9b7e153bc496a06dbabeea0f4f

To run the program without compiling you can do the following

go run md5sum.go <filename>

Conclusion

In this very first version we saw how we can create a very simple Go program that calculates the hash of a file, in the next version we will add the option to read file contents from STDIN, which can be very useful when used with other scripts or in cases we want to calculate md5 hash of a string and not a file.