Generate CRC32 hash of a file in Golang turorial
In previous posts I showed how to make a MD5 hash and a SHA1 hash of a file, generating a CRC checksum on a file is however a bit more complicated since it uses a polynomial table. I'll explain everything in depth.
Polynomial tables
A polynomial table is a table that gets constructed by a specified polynomial, Go does this for you with the function MakeTable in the hash/crc32 package. In simple words the table tells how the CRC hash should be calculated.
There are five used CRC-32 standards.
Name | Uses | Polynomial representation (reversed) |
CRC-32 | Layer 2 ethernet network and SATA error detection. Checksums for PNG, MPEG-2, Gzip, Bzip2,... | 0xEDB88320 |
CRC-32C (Castagnoli) | Error detection in iSCSI. Checksums for Btrfs, ext4,... | 0x82F63B78 |
CRC-32K (Koopman) | 0xEB31D82E | |
CRC-32K2 (Koopman 2) | 0x992C1A4C | |
CRC-32Q | Error detection in aviation communications AIXM | 0xD5828281 |
A Golang function
This function requires two arguments in the parameters, the first one a string to the location of your file and the second one a unsigned 32bit reversed polynomial representation. It returns either the CRC hash if no error has occurred or an error.
The function
import (
"encoding/hex"
"fmt"
"hash/crc32"
"io"
"os"
)
func hash_file_crc32(filePath string, polynomial uint32) (string, error) {
//Initialize an empty return string now in case an error has to be returned
var returnCRC32String string
//Open the fhe file located at the given path and check for errors
file, err := os.Open(filePath)
if err != nil {
return returnCRC32String, err
}
//Tell the program to close the file when the function returns
defer file.Close()
//Create the table with the given polynomial
tablePolynomial := crc32.MakeTable(polynomial)
//Open a new hash interface to write the file to
hash := crc32.New(tablePolynomial)
//Copy the file in the interface
if _, err := io.Copy(hash, file); err != nil {
return returnCRC32String, err
}
//Generate the hash
hashInBytes := hash.Sum(nil)[:]
//Encode the hash to a string
returnCRC32String = hex.EncodeToString(hashInBytes)
//Return the output
return returnCRC32String, nil
}
Example
This example will print out the CRC-32 hash of itself, the running program.
package main
import (
"encoding/hex"
"fmt"
"hash/crc32"
"io"
"os"
)
func hash_file_crc32(filePath string, polynomial uint32) (string, error) {
var returnCRC32String string
file, err := os.Open(filePath)
if err != nil {
return returnCRC32String, err
}
defer file.Close()
tablePolynomial := crc32.MakeTable(polynomial)
hash := crc32.New(tablePolynomial)
if _, err := io.Copy(hash, file); err != nil {
return returnCRC32String, err
}
hashInBytes := hash.Sum(nil)[:]
returnCRC32String = hex.EncodeToString(hashInBytes)
return returnCRC32String, nil
}
func main() {
hash, err := hash_file_crc32(os.Args[0], 0xedb88320)
if err == nil {
fmt.Println(hash)
}
}
More about CRC
https://en.wikipedia.org/wiki/Cyclic_redundancy_check
cached copy