Skip to content

Instantly share code, notes, and snippets.

@mrichman
Last active May 24, 2017 11:39
Show Gist options
  • Save mrichman/518cb49e20b24176f32c5d8c9e21959f to your computer and use it in GitHub Desktop.
Save mrichman/518cb49e20b24176f32c5d8c9e21959f to your computer and use it in GitHub Desktop.
Compute hash of a resource at a URL
package main
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/tls"
"encoding/hex"
"flag"
"fmt"
"hash"
"io"
"net/http"
"os"
log "github.com/sirupsen/logrus"
)
// PassThru wraps an existing io.Reader.
//
// It simply forwards the Read() call, while displaying
// the results from individual calls to it.
type PassThru struct {
io.Reader
total int64 // Total # of bytes transferred
length int64 // Expected length
progress float64
}
func main() {
alg := flag.String("a", "SHA256", "algorithm to use (defaults to SHA256)")
url := flag.String("u", "", "URL of file to hash")
skip := flag.Bool("s", false, "skip SSL verification")
flag.Parse()
if *url == "" {
log.Fatalf("No URL specified")
}
var hasher hash.Hash
switch *alg {
case "MD5":
hasher = md5.New()
case "SHA1":
hasher = sha1.New()
case "SHA256":
hasher = sha256.New()
case "SHA512":
hasher = sha512.New()
default:
log.Fatalf("Unsupported algorithm: %s", *alg)
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: *skip},
}
client := &http.Client{Transport: tr}
response, e := client.Get(*url)
if e != nil {
log.Fatal(e)
}
defer response.Body.Close()
readerpt := &PassThru{Reader: response.Body, length: response.ContentLength}
if _, err := io.Copy(hasher, readerpt); err != nil {
log.Fatalf("Error hashing URL: %v", err)
}
result := hex.EncodeToString(hasher.Sum(nil))
fmt.Printf("%s", result)
}
// Read 'overrides' the underlying io.Reader's Read method.
// This is the one that will be called by io.Copy(). We simply
// use it to keep track of byte counts and then forward the call.
func (pt *PassThru) Read(p []byte) (int, error) {
n, err := pt.Reader.Read(p)
if n > 0 {
pt.total += int64(n)
percentage := float64(pt.total) / float64(pt.length) * float64(100)
i := int(percentage / float64(10))
is := fmt.Sprintf("%v", i)
if percentage-pt.progress > 2 {
fmt.Fprintf(os.Stderr, is)
pt.progress = percentage
}
}
return n, err
}
package main
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/tls"
"encoding/hex"
"flag"
"fmt"
"hash"
"io"
"net/http"
log "github.com/sirupsen/logrus"
)
func main() {
alg := flag.String("a", "SHA256", "algorithm to use (defaults to SHA256)")
url := flag.String("u", "", "URL of file to hash")
skip := flag.Bool("s", false, "skip SSL verification")
flag.Parse()
if *url == "" {
log.Fatalf("No URL specified")
}
var hasher hash.Hash
switch *alg {
case "MD5":
hasher = md5.New()
case "SHA1":
hasher = sha1.New()
case "SHA256":
hasher = sha256.New()
case "SHA512":
hasher = sha512.New()
default:
log.Fatalf("Unsupported algorithm: %s", *alg)
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: *skip},
}
client := &http.Client{Transport: tr}
response, e := client.Get(*url)
if e != nil {
log.Fatal(e)
}
defer response.Body.Close()
if _, err := io.Copy(hasher, response.Body); err != nil {
log.Fatalf("Error hashing URL: %v", err)
}
result := hex.EncodeToString(hasher.Sum(nil))
fmt.Printf("%s", result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment