mirror of
https://github.com/emojisum/emojisum.git
synced 2024-11-30 10:55:39 +00:00
*: moving to a repo
Since this was initially on https://gist.github.com/vbatts/ed28cddc23d6d2123e0c0295b278471b Folks asked for this to be `go get`'able. Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
parent
b049d4d104
commit
a8885e2038
2 changed files with 498 additions and 0 deletions
57
README.md
Normal file
57
README.md
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# emojisum
|
||||||
|
|
||||||
|
:pray: :paperclip: Emoji that checksum! :tada: :poop:
|
||||||
|
|
||||||
|
I attempted a curated list of 256 emojis that are not entirely similar. Using http://www.webpagefx.com/tools/emoji-cheat-sheet/ to compare them. I went with 256 as that is 8bit/1byte, and the hexadecimal output that is 2 hex characters.
|
||||||
|
|
||||||
|
So 1 emoji is 2 hex positions.
|
||||||
|
|
||||||
|
## build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/vbatts/emojisum
|
||||||
|
```
|
||||||
|
|
||||||
|
## usage
|
||||||
|
|
||||||
|
This uses [`github.com/kyokomi/emoji`](https://github.com/kyokomi/emoji) to print to the console, but also gives the string ouptut for easy pasting to github/markdown.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$> emojisum main.go
|
||||||
|
SHA1(main.go)= 14b09535217ca8f5f47f4665e2266e686f0728b4
|
||||||
|
SHA1(main.go)= :bird::red_car::on::crystal_ball::calendar::lemon::pray::warning::violin::lollipop::facepunch::hearts::tm::children_crossing::hourglass::heavy_plus_sign::house::ant::clap::rocket:
|
||||||
|
SHA1(main.go)= 🐦 🚗 🔛 🔮 📆 🍋 🙏 ⚠️🎻 🍭 👊 ♥️™️🚸 ⌛️➕ 🏠 🐜 👏 🚀
|
||||||
|
```
|
||||||
|
|
||||||
|
Like so!
|
||||||
|
|
||||||
|
SHA1(main.go)= :bird::red_car::on::crystal_ball::calendar::lemon::pray::warning::violin::lollipop::facepunch::hearts::tm::children_crossing::hourglass::heavy_plus_sign::house::ant::clap::rocket:
|
||||||
|
|
||||||
|
|
||||||
|
### pass in the checksums
|
||||||
|
|
||||||
|
Rather than relying on this simple tool to do the checksum itself, you will likely want to rely on OpenSSL or coreutils for checksumming.
|
||||||
|
`emojisum` can just take those formats on stdin:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$> sha1sum main.go | emojisum -parse-coreutils
|
||||||
|
7656835947b4c6da272023c56b6f2529511bf88b main.go
|
||||||
|
:jp::gb::metal::goat::family::rocket::smiley_cat::swimmer::chocolate_bar::cactus::candy::smile::honeybee::house::cherries::cloud::fries::bow::wavy_dash::musical_score: main.go
|
||||||
|
🇯🇵 🇬🇧 🤘 🐐 👪 🚀 😺 🏊 🍫 🌵 🍬 😄 🐝 🏠 🍒 ☁️🍟 🙇 〰️ 🎼 main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
Like so:
|
||||||
|
|
||||||
|
🇯🇵 🇬🇧 🤘 🐐 👪 🚀 😺 🏊 🍫 🌵 🍬 😄 🐝 🏠 🍒 ☁️🍟 🙇 〰️ 🎼 main.go
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$> openssl sha1 main.go |emojisum -parse-openssl
|
||||||
|
SHA1(main.go)= 7656835947b4c6da272023c56b6f2529511bf88b
|
||||||
|
SHA1(main.go)= :jp::gb::metal::goat::family::rocket::smiley_cat::swimmer::chocolate_bar::cactus::candy::smile::honeybee::house::cherries::cloud::fries::bow::wavy_dash::musical_score:
|
||||||
|
SHA1(main.go)= 🇯🇵 🇬🇧 🤘 🐐 👪 🚀 😺 🏊 🍫 🌵 🍬 😄 🐝 🏠 🍒 ☁️🍟 🙇 〰️ 🎼
|
||||||
|
```
|
||||||
|
|
||||||
|
And like so:
|
||||||
|
|
||||||
|
SHA1(main.go)= 🇯🇵 🇬🇧 🤘 🐐 👪 🚀 😺 🏊 🍫 🌵 🍬 😄 🐝 🏠 🍒 ☁️🍟 🙇 〰️ 🎼
|
441
main.go
Normal file
441
main.go
Normal file
|
@ -0,0 +1,441 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/kyokomi/emoji"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := run(); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
flParseOpenSSL = flag.Bool("parse-openssl", false, "parse the output of OpenSSL style checksums on stdin (`openssl sha256 ./foo | emojisum -parse-openssl`)")
|
||||||
|
flParseCoreUtils = flag.Bool("parse-coreutils", false, "parse the output of CoreUtils style checksums on stdin (`sha256sum ./foo | emojisum -parse-coreutils`)")
|
||||||
|
)
|
||||||
|
|
||||||
|
func run() error {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *flParseOpenSSL {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if *flParseCoreUtils {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise do the checksum ourselves
|
||||||
|
|
||||||
|
if flag.NArg() == 0 {
|
||||||
|
sum, err := Sum(os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
str := emojiFromBytes(sum)
|
||||||
|
fmt.Printf("SHA1(-)=\t%x\n", sum)
|
||||||
|
fmt.Printf("SHA1(-)=\t%s\n", str)
|
||||||
|
fmt.Printf("SHA1(-)=\t")
|
||||||
|
emoji.Println(str)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, arg := range flag.Args() {
|
||||||
|
fh, err := os.Open(arg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
|
||||||
|
sum, err := Sum(fh)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
str := emojiFromBytes(sum)
|
||||||
|
fmt.Printf("SHA1(%s)=\t%x\n", arg, sum)
|
||||||
|
fmt.Printf("SHA1(%s)=\t%s\n", arg, str)
|
||||||
|
fmt.Printf("SHA1(%s)=\t", arg)
|
||||||
|
emoji.Println(str)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrNotCoreUtilsLine = errors.New("not a coreutils checksum line")
|
||||||
|
|
||||||
|
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 {
|
||||||
|
ret = ret + emojiFromRune(b)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func emojiFromRune(b byte) string {
|
||||||
|
//fmt.Printf("%#v\n", b)
|
||||||
|
return emojiMap[int(b)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// these are an ordered list, referened by a byte (each byte of a checksum digest)
|
||||||
|
var emojiMap = []string{
|
||||||
|
":+1:",
|
||||||
|
":8ball:",
|
||||||
|
":airplane:",
|
||||||
|
":alien:",
|
||||||
|
":anchor:",
|
||||||
|
":angel:",
|
||||||
|
":angry:",
|
||||||
|
":ant:",
|
||||||
|
":apple:",
|
||||||
|
":art:",
|
||||||
|
":baby:",
|
||||||
|
":baby_bottle:",
|
||||||
|
":back:",
|
||||||
|
":bamboo:",
|
||||||
|
":banana:",
|
||||||
|
":barber:",
|
||||||
|
":bathtub:",
|
||||||
|
":beer:",
|
||||||
|
":bell:",
|
||||||
|
":bicyclist:",
|
||||||
|
":bird:",
|
||||||
|
":birthday:",
|
||||||
|
":blossom:",
|
||||||
|
":blue_car:",
|
||||||
|
":boar:",
|
||||||
|
":bomb:",
|
||||||
|
":boom:",
|
||||||
|
":bow:",
|
||||||
|
":boy:",
|
||||||
|
":broken_heart:",
|
||||||
|
":bulb:",
|
||||||
|
":bus:",
|
||||||
|
":cactus:",
|
||||||
|
":calendar:",
|
||||||
|
":camera:",
|
||||||
|
":candy:",
|
||||||
|
":cat:",
|
||||||
|
":cherries:",
|
||||||
|
":children_crossing:",
|
||||||
|
":chocolate_bar:",
|
||||||
|
":clap:",
|
||||||
|
":cloud:",
|
||||||
|
":clubs:",
|
||||||
|
":cn:",
|
||||||
|
":coffee:",
|
||||||
|
":construction:",
|
||||||
|
":cookie:",
|
||||||
|
":copyright:",
|
||||||
|
":corn:",
|
||||||
|
":cow:",
|
||||||
|
":crescent_moon:",
|
||||||
|
":crown:",
|
||||||
|
":cry:",
|
||||||
|
":crystal_ball:",
|
||||||
|
":curly_loop:",
|
||||||
|
":dancers:",
|
||||||
|
":dash:",
|
||||||
|
":de:",
|
||||||
|
":diamonds:",
|
||||||
|
":dog:",
|
||||||
|
":doughnut:",
|
||||||
|
":dragon:",
|
||||||
|
":dvd:",
|
||||||
|
":ear:",
|
||||||
|
":eggplant:",
|
||||||
|
":elephant:",
|
||||||
|
":end:",
|
||||||
|
":envelope:",
|
||||||
|
":es:",
|
||||||
|
":eyes:",
|
||||||
|
":facepunch:",
|
||||||
|
":family:",
|
||||||
|
":ferris_wheel:",
|
||||||
|
":finnadie:",
|
||||||
|
":fire:",
|
||||||
|
":fireworks:",
|
||||||
|
":floppy_disk:",
|
||||||
|
":football:",
|
||||||
|
":fork_and_knife:",
|
||||||
|
":four_leaf_clover:",
|
||||||
|
":fr:",
|
||||||
|
":fries:",
|
||||||
|
":frog:",
|
||||||
|
":fu:",
|
||||||
|
":full_moon:",
|
||||||
|
":game_die:",
|
||||||
|
":gb:",
|
||||||
|
":gem:",
|
||||||
|
":girl:",
|
||||||
|
":goat:",
|
||||||
|
":grimacing:",
|
||||||
|
":grin:",
|
||||||
|
":guardsman:",
|
||||||
|
":guitar:",
|
||||||
|
":gun:",
|
||||||
|
":hamburger:",
|
||||||
|
":hammer:",
|
||||||
|
":hamster:",
|
||||||
|
":hear_no_evil:",
|
||||||
|
":heart:",
|
||||||
|
":heart_eyes_cat:",
|
||||||
|
":hearts:",
|
||||||
|
":heavy_check_mark:",
|
||||||
|
":moyai:",
|
||||||
|
":izakaya_lantern:",
|
||||||
|
":helicopter:",
|
||||||
|
":hocho:",
|
||||||
|
":honeybee:",
|
||||||
|
":horse:",
|
||||||
|
":horse_racing:",
|
||||||
|
":hourglass:",
|
||||||
|
":house:",
|
||||||
|
":hurtrealbad:",
|
||||||
|
":icecream:",
|
||||||
|
":imp:",
|
||||||
|
":it:",
|
||||||
|
":jack_o_lantern:",
|
||||||
|
":japanese_goblin:",
|
||||||
|
":jp:",
|
||||||
|
":key:",
|
||||||
|
":kiss:",
|
||||||
|
":kissing_cat:",
|
||||||
|
":koala:",
|
||||||
|
":kr:",
|
||||||
|
":lemon:",
|
||||||
|
":lipstick:",
|
||||||
|
":lock:",
|
||||||
|
":lollipop:",
|
||||||
|
":man:",
|
||||||
|
":maple_leaf:",
|
||||||
|
":mask:",
|
||||||
|
":metal:",
|
||||||
|
":microscope:",
|
||||||
|
":moneybag:",
|
||||||
|
":monkey:",
|
||||||
|
":mount_fuji:",
|
||||||
|
":muscle:",
|
||||||
|
":mushroom:",
|
||||||
|
":musical_keyboard:",
|
||||||
|
":musical_score:",
|
||||||
|
":nail_care:",
|
||||||
|
":new_moon:",
|
||||||
|
":no_entry:",
|
||||||
|
":nose:",
|
||||||
|
":notes:",
|
||||||
|
":nut_and_bolt:",
|
||||||
|
":o:",
|
||||||
|
":ocean:",
|
||||||
|
":ok_hand:",
|
||||||
|
":on:",
|
||||||
|
":package:",
|
||||||
|
":palm_tree:",
|
||||||
|
":panda_face:",
|
||||||
|
":paperclip:",
|
||||||
|
":partly_sunny:",
|
||||||
|
":passport_control:",
|
||||||
|
":paw_prints:",
|
||||||
|
":peach:",
|
||||||
|
":penguin:",
|
||||||
|
":phone:",
|
||||||
|
":pig:",
|
||||||
|
":pill:",
|
||||||
|
":pineapple:",
|
||||||
|
":pizza:",
|
||||||
|
":point_left:",
|
||||||
|
":point_right:",
|
||||||
|
":poop:",
|
||||||
|
":poultry_leg:",
|
||||||
|
":pray:",
|
||||||
|
":princess:",
|
||||||
|
":purse:",
|
||||||
|
":pushpin:",
|
||||||
|
":rabbit:",
|
||||||
|
":rainbow:",
|
||||||
|
":raised_hand:",
|
||||||
|
":recycle:",
|
||||||
|
":red_car:",
|
||||||
|
":registered:",
|
||||||
|
":ribbon:",
|
||||||
|
":rice:",
|
||||||
|
":rocket:",
|
||||||
|
":roller_coaster:",
|
||||||
|
":rooster:",
|
||||||
|
":ru:",
|
||||||
|
":sailboat:",
|
||||||
|
":santa:",
|
||||||
|
":satellite:",
|
||||||
|
":satisfied:",
|
||||||
|
":saxophone:",
|
||||||
|
":scissors:",
|
||||||
|
":see_no_evil:",
|
||||||
|
":sheep:",
|
||||||
|
":shell:",
|
||||||
|
":shoe:",
|
||||||
|
":ski:",
|
||||||
|
":skull:",
|
||||||
|
":sleepy:",
|
||||||
|
":smile:",
|
||||||
|
":smiley_cat:",
|
||||||
|
":smirk:",
|
||||||
|
":smoking:",
|
||||||
|
":snail:",
|
||||||
|
":snake:",
|
||||||
|
":snowflake:",
|
||||||
|
":soccer:",
|
||||||
|
":soon:",
|
||||||
|
":space_invader:",
|
||||||
|
":spades:",
|
||||||
|
":speak_no_evil:",
|
||||||
|
":star:",
|
||||||
|
":stars:",
|
||||||
|
":statue_of_liberty:",
|
||||||
|
":steam_locomotive:",
|
||||||
|
":sunflower:",
|
||||||
|
":sunglasses:",
|
||||||
|
":sunny:",
|
||||||
|
":sunrise:",
|
||||||
|
":surfer:",
|
||||||
|
":swimmer:",
|
||||||
|
":syringe:",
|
||||||
|
":tada:",
|
||||||
|
":tangerine:",
|
||||||
|
":taxi:",
|
||||||
|
":tennis:",
|
||||||
|
":tent:",
|
||||||
|
":thought_balloon:",
|
||||||
|
":tm:",
|
||||||
|
":toilet:",
|
||||||
|
":tongue:",
|
||||||
|
":tophat:",
|
||||||
|
":tractor:",
|
||||||
|
":trolleybus:",
|
||||||
|
":trollface:",
|
||||||
|
":trophy:",
|
||||||
|
":trumpet:",
|
||||||
|
":turtle:",
|
||||||
|
":two_men_holding_hands:",
|
||||||
|
":two_women_holding_hands:",
|
||||||
|
":uk:",
|
||||||
|
":umbrella:",
|
||||||
|
":unlock:",
|
||||||
|
":us:",
|
||||||
|
":v:",
|
||||||
|
":vhs:",
|
||||||
|
":violin:",
|
||||||
|
":warning:",
|
||||||
|
":watermelon:",
|
||||||
|
":wave:",
|
||||||
|
":wavy_dash:",
|
||||||
|
":wc:",
|
||||||
|
":wheelchair:",
|
||||||
|
":woman:",
|
||||||
|
":x:",
|
||||||
|
":yum:",
|
||||||
|
":zap:",
|
||||||
|
":zzz:",
|
||||||
|
}
|
Loading…
Reference in a new issue