diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2fe1c5e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Gregory Pomerantz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c1437de --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# b3sum + +A golang port of b3sum + +This is a simple `b3sum` command using `github.com/zeebo/blake3`. + +``` +Usage: + b3sum [flags] [file]... + -h Prints help information + -l int + The number of output bytes, prior to hex encoding (default 32) + -p int + The maximum concurrency (defaults to the number of CPUs) +``` + +If no input files are specified, `b3sum` reads `stdin`. + diff --git a/main.go b/main.go index 80d9afd..61f0793 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "runtime" "sync" "github.com/zeebo/blake3" @@ -14,45 +15,53 @@ import ( var ( help = flag.Bool("h", false, "Prints help information") length = flag.Int("l", 32, "The number of output bytes, prior to hex encoding") - par = flag.Int("p", 4, "The maximum concurrency") + par = flag.Int("p", runtime.NumCPU(), "The maximum concurrency") ) func main() { flag.Parse() - if *help || len(flag.Args()) == 0 || *par < 1 { + if *help || *par < 1 { flag.Usage() os.Exit(0) } - q := make(chan struct{}, *par) - wg := &sync.WaitGroup{} - - for _, name := range flag.Args() { - q <- struct{}{} - wg.Add(1) - go func(name string) { - buf := [65536]byte{} - file, err := os.Open(name) - if err != nil { + sum := func(file io.ReadCloser) string { + buf := [65536]byte{} + hasher := blake3.NewSized(*length) + for { + n, err := file.Read(buf[:]) + hasher.Write(buf[:n]) + if err == io.EOF { + break + } else if err != nil { panic(err) } - hasher := blake3.NewSized(*length) - for { - n, err := file.Read(buf[:]) - hasher.Write(buf[:n]) - if err == io.EOF { - break - } else if err != nil { + } + file.Close() + hash := hasher.Sum([]byte{}) + return hex.EncodeToString(hash) + } + + if len(flag.Args()) == 0 { + fmt.Println(sum(os.Stdin)) + } else { + q := make(chan struct{}, *par) + wg := &sync.WaitGroup{} + + for _, name := range flag.Args() { + q <- struct{}{} + wg.Add(1) + go func(name string) { + file, err := os.Open(name) + if err != nil { panic(err) } - } - file.Close() - hash := hasher.Sum([]byte{}) - fmt.Print(hex.EncodeToString(hash)) - fmt.Print(" ") - fmt.Println(name) - <- q - wg.Done() - }(name) + fmt.Print(sum(file)) + fmt.Print(" ") + fmt.Println(name) + <- q + wg.Done() + }(name) + } + wg.Wait() } - wg.Wait() }