Created
August 24, 2020 09:40
-
-
Save charlieegan3/ad144b6126d65b42325910267098f8f0 to your computer and use it in GitHub Desktop.
Dropbox Content Hash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dropbox | |
import ( | |
"crypto/sha256" | |
"fmt" | |
"os" | |
"github.com/pkg/errors" | |
) | |
// ContentHash performs the dropbox content hash sum for a file on disk | |
func ContentHash(path string) (string, error) { | |
file, err := os.Open(path) | |
if err != nil { | |
return "", errors.Wrap(err, "failed to open the file for reading") | |
} | |
defer file.Close() | |
fi, err := file.Stat() | |
if err != nil { | |
return "", errors.Wrap(err, "failed to check the size of the file") | |
} | |
remainingBytes := fi.Size() | |
blockSize := int64(4 * 1024 * 1024) | |
// bytes from the shasums of each block | |
blockSHABytes := []byte{} | |
for { | |
// bytes to read this time round | |
bytesToRead := remainingBytes | |
// don't read more than a block | |
if bytesToRead > blockSize { | |
bytesToRead = blockSize | |
} | |
// read that number of bytes | |
byteSlice := make([]byte, bytesToRead) | |
bytesRead, err := file.Read(byteSlice) | |
if err != nil { | |
return "", errors.Wrap(err, "failed to read block of bytes from file") | |
} | |
// update the remainingBytes, less the bytes we just read | |
remainingBytes -= int64(bytesRead) | |
// compute the shasum bytes for that block | |
shaData := sha256.Sum256(byteSlice) | |
// append the shasum bytes to the shasum bytes for the other blocks | |
blockSHABytes = append(blockSHABytes, shaData[:]...) | |
// exit if we don't need to read another block | |
if int64(bytesRead) < blockSize { | |
break | |
} | |
} | |
// return a hex formatted string of the concatenated shasums, shasummed again | |
return fmt.Sprintf("%x", sha256.Sum256(blockSHABytes)), nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment