diff --git a/README.md b/README.md index 6e29592..b56af37 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Emojisum +[![Build Status](https://travis-ci.org/emojisum/emojisum.svg?branch=master)](https://travis-ci.org/emojisum/emojisum) -:pray: :paperclip: An easier way to compare hashes /fingerprints, when dealing with the human weak link :link: :tada: +:pray: :paperclip: Emoji that checksum! :tada: :poop: A curated list of 256 emojis that are not entirely similar. Using http://www.webpagefx.com/tools/emoji-cheat-sheet/ and http://www.unicode.org/emoji/charts/full-emoji-list.html to compare them. diff --git a/cmd/coreutils.go b/cmd/coreutils.go deleted file mode 100644 index 6bf06a7..0000000 --- a/cmd/coreutils.go +++ /dev/null @@ -1,61 +0,0 @@ -package cmd - -import ( - "bufio" - "encoding/hex" - "errors" - "fmt" - "io" - "os" - "strings" - - "github.com/kyokomi/emoji" -) - -/* -ParseCoreUtils expects some input like: -```shell -$ sha256sum ./tmp.efLuko -f18bd8b680e834ab8097a66deb0255821195d9624e39da6b65903ff6a09a01bb ./tmp.efLuko -``` -*/ -func ParseCoreUtils(line string) (filename string, sum []byte, err error) { - chunks := strings.SplitN(strings.TrimRight(line, "\n"), " ", 2) - if len(chunks) != 2 { - return "", nil, ErrNotCoreUtilsLine - } - sum, err = hex.DecodeString(chunks[0]) - if err != nil { - return "", nil, err - } - return chunks[1], sum, nil -} - -// ErrNotCoreUtilsLine when the line to parse is not formated like a coreutils checksum line -var ErrNotCoreUtilsLine = errors.New("not a coreutils checksum line") - -// PrintCoreUtils reads in the content like from `sha25sum ...` and returns -// in likeness but with emojisum instead. -// TODO(vb) return a buffer that the caller can choose to print out themselves -func PrintCoreUtils(rdr io.Reader) error { - buf := bufio.NewReader(rdr) - for { - line, err := buf.ReadString('\n') - if err != nil && err == io.EOF { - break - } else if err != nil { - return err - } - name, sum, err := ParseCoreUtils(line) - if err != nil { - fmt.Fprintf(os.Stderr, "%s: %q\n", err, line) - continue - } - str := EmojiFromBytes(sum) - fmt.Printf("%x %s\n", sum, name) - fmt.Printf("%s %s\n", str, name) - emoji.Print(str) - fmt.Printf(" %s\n", name) - } - return nil -} diff --git a/cmd/emoji.go b/cmd/emoji.go deleted file mode 100644 index 7907bcf..0000000 --- a/cmd/emoji.go +++ /dev/null @@ -1,21 +0,0 @@ -package cmd - -import ( - esum "github.com/emojisum/emojisum/emoji" -) - -// EmojiFromBytes parses the bytes buffer for colon notation and returns the -// corresponding emoji -func EmojiFromBytes(buf []byte) string { - var ret string - for _, b := range buf { - for _, e := range esum.Map(b) { - // use the first colon notation word and continue - if esum.IsColonNotation(e) { - ret = ret + e - break - } - } - } - return ret -} diff --git a/cmd/openssl.go b/cmd/openssl.go deleted file mode 100644 index b351d83..0000000 --- a/cmd/openssl.go +++ /dev/null @@ -1,68 +0,0 @@ -package cmd - -import ( - "bufio" - "encoding/hex" - "errors" - "fmt" - "io" - "os" - "strings" - - "github.com/kyokomi/emoji" -) - -/* -ParseOpenSSL expects some input like: -```shell -$> openssl sha256 tmp.efLuko -SHA256(tmp.efLuko)= f18bd8b680e834ab8097a66deb0255821195d9624e39da6b65903ff6a09a01bb -``` -*/ -func ParseOpenSSL(line string) (hash, filename string, sum []byte, err error) { - if !strings.Contains(line, "(") { - return "", "", nil, ErrNotOpenSSLLine - } - chunks := strings.SplitN(strings.TrimRight(line, "\n"), ")= ", 2) - if len(chunks) != 2 { - return "", "", nil, ErrNotOpenSSLLine - } - chunksprime := strings.SplitN(chunks[0], "(", 2) - if len(chunks) != 2 { - return "", "", nil, ErrNotOpenSSLLine - } - sum, err = hex.DecodeString(chunks[1]) - if err != nil { - return "", "", nil, err - } - return chunksprime[0], chunksprime[1], sum, nil -} - -// ErrNotOpenSSLLine when the line to parse is not formated like an OpenSSL checksum line -var ErrNotOpenSSLLine = errors.New("not an openssl checksum line") - -// PrintOpenSSL reads in the content like from `openssl sha25 ...` and returns -// in likeness but with emojisum instead. -// TODO(vb) return a buffer that the caller can choose to print out themselves -func PrintOpenSSL(rdr io.Reader) error { - buf := bufio.NewReader(rdr) - for { - line, err := buf.ReadString('\n') - if err != nil && err == io.EOF { - break - } else if err != nil { - return err - } - hash, name, sum, err := ParseOpenSSL(line) - if err != nil { - fmt.Fprintf(os.Stderr, "%s: %q\n", err, line) - continue - } - str := EmojiFromBytes(sum) - fmt.Printf("%s(%s)= %x\n", hash, name, sum) - fmt.Printf("%s(%s)= %s\n", hash, name, str) - fmt.Printf("%s(%s)= ", hash, name) - emoji.Println(str) - } - return nil -} diff --git a/emoji/go.mod b/emoji/go.mod new file mode 100644 index 0000000..627fae2 --- /dev/null +++ b/emoji/go.mod @@ -0,0 +1,3 @@ +module github.com/emojisum/emojisum/emoji + +go 1.17 diff --git a/main.go b/main.go index 5b3ad3f..06c57c2 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,17 @@ package main import ( + "bufio" + "crypto/sha1" + "encoding/hex" + "errors" "flag" "fmt" + "io" "os" + "strings" - "github.com/emojisum/emojisum/cmd" + esum "github.com/emojisum/emojisum/emoji" "github.com/kyokomi/emoji" ) @@ -25,20 +31,58 @@ func run() error { flag.Parse() if *flParseOpenSSL { - return cmd.PrintOpenSSL(os.Stdin) + buf := bufio.NewReader(os.Stdin) + for { + line, err := buf.ReadString('\n') + if err != nil && err == io.EOF { + return nil + } else if err != nil { + return err + } + hash, name, sum, err := parseOpenSSL(line) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %q\n", err, line) + continue + } + str := emojiFromBytes(sum) + fmt.Printf("%s(%s)= %x\n", hash, name, sum) + fmt.Printf("%s(%s)= %s\n", hash, name, str) + fmt.Printf("%s(%s)= ", hash, name) + emoji.Println(str) + } + // never gets here because of the return on EOF or err } if *flParseCoreUtils { - return cmd.PrintCoreUtils(os.Stdin) + buf := bufio.NewReader(os.Stdin) + for { + line, err := buf.ReadString('\n') + if err != nil && err == io.EOF { + return nil + } else if err != nil { + return err + } + name, sum, err := parseCoreUtils(line) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %q\n", err, line) + continue + } + str := emojiFromBytes(sum) + fmt.Printf("%x %s\n", sum, name) + fmt.Printf("%s %s\n", str, name) + emoji.Print(str) + fmt.Printf(" %s\n", name) + } + // never gets here because of the return on EOF or err } // Otherwise do the checksum ourselves if flag.NArg() == 0 { - sum, err := cmd.Sum(os.Stdin) + sum, err := Sum(os.Stdin) if err != nil { return err } - str := cmd.EmojiFromBytes(sum) + str := emojiFromBytes(sum) fmt.Printf("SHA1(-)= %x\n", sum) fmt.Printf("SHA1(-)= %s\n", str) fmt.Printf("SHA1(-)= ") @@ -53,11 +97,11 @@ func run() error { } defer fh.Close() - sum, err := cmd.Sum(fh) + sum, err := Sum(fh) if err != nil { return err } - str := cmd.EmojiFromBytes(sum) + str := emojiFromBytes(sum) fmt.Printf("SHA1(%s)= %x\n", arg, sum) fmt.Printf("SHA1(%s)= %s\n", arg, str) fmt.Printf("SHA1(%s)= ", arg) @@ -65,3 +109,78 @@ func run() error { } return nil } + +/* +openssl sum: +``` +$> openssl sha256 tmp.efLuko +SHA256(tmp.efLuko)= f18bd8b680e834ab8097a66deb0255821195d9624e39da6b65903ff6a09a01bb +``` +*/ +func parseOpenSSL(line string) (hash, filename string, sum []byte, err error) { + if !strings.Contains(line, "(") { + return "", "", nil, ErrNotOpenSSLLine + } + chunks := strings.SplitN(strings.TrimRight(line, "\n"), ")= ", 2) + if len(chunks) != 2 { + return "", "", nil, ErrNotOpenSSLLine + } + chunksprime := strings.SplitN(chunks[0], "(", 2) + if len(chunks) != 2 { + return "", "", nil, ErrNotOpenSSLLine + } + sum, err = hex.DecodeString(chunks[1]) + if err != nil { + return "", "", nil, err + } + return chunksprime[0], chunksprime[1], sum, nil +} + +// ErrNotOpenSSLLine when the line to parse is not formated like an OpenSSL checksum line +var ErrNotOpenSSLLine = errors.New("not an openssl checksum line") + +/* +coreutils output: +``` +$ sha256sum ./tmp.efLuko +f18bd8b680e834ab8097a66deb0255821195d9624e39da6b65903ff6a09a01bb ./tmp.efLuko +``` +*/ +func parseCoreUtils(line string) (filename string, sum []byte, err error) { + chunks := strings.SplitN(strings.TrimRight(line, "\n"), " ", 2) + if len(chunks) != 2 { + return "", nil, ErrNotCoreUtilsLine + } + sum, err = hex.DecodeString(chunks[0]) + if err != nil { + return "", nil, err + } + return chunks[1], sum, nil +} + +// ErrNotCoreUtilsLine when the line to parse is not formated like a coreutils checksum line +var ErrNotCoreUtilsLine = errors.New("not a coreutils checksum line") + +// Sum is a basic wrapper around crypto/sha1 +func Sum(r io.Reader) ([]byte, error) { + h := sha1.New() + if _, err := io.Copy(h, r); err != nil { + return nil, err + } + sum := h.Sum(nil) + return sum[:], nil +} + +func emojiFromBytes(buf []byte) string { + var ret string + for _, b := range buf { + for _, e := range esum.Map(b) { + // use the first colon notation word and continue + if esum.IsColonNotation(e) { + ret = ret + e + break + } + } + } + return ret +}