I wrote a simpleIdenticon generator in Go.
Usage
go run main.go -inputs=abcde
"abcde" will be hashed, then generates a png file
go run main.go -h // check how to use
Code
The directory
.├── avatarme│ └── avatarme.go├── go.mod├── go.sum└── main.go
main.go
packagemainimport("main/avatarme")funcmain(){avatarme:=avatarme.Avatarme{}avatarme.Generate()// it generates .png file}
avatarme.go
packageavatarmeimport("flag""fmt""os""log""image""image/color""image/draw""image/png""crypto/sha1""crypto/sha256""crypto/sha512""encoding/hex""math")// default valueconst(SHA1=iota// 0SHA224// 1SHA256// 2SHA384// 3SHA512// 4)consthashAlgDescstring="0 (SHA-1)\n1 (SHA-224)\n2 (SHA-256)\n3 (SHA-384)\n4 (SHA-512)\n"const(hashAlgDefault=SHA512sizeDefault=50mutltiple=5numberHash=3)typeAvatarmestruct{inputsstringhashAlgPtr,sizePtr*int}// package initfuncinit(){flag.Usage=func(){fmt.Fprintf(os.Stderr,"Usage: go run cli.go [options]\n")fmt.Fprintf(os.Stderr,"e.g. go run cli.go -hashAlg=2\n")flag.PrintDefaults()}iflen(os.Args)<2{log.Fatal("expected at least two arguments")os.Exit(1)}}func(opts*Avatarme)SetOpts(){flag.StringVar(&opts.inputs,"inputs","","inputs desc")opts.hashAlgPtr=flag.Int("hashAlg",hashAlgDefault,hashAlgDesc)opts.sizePtr=flag.Int("size",sizeDefault,"size desc")flag.Parse()if*opts.sizePtr<sizeDefault{log.Fatalf("size at least 50, but yours is %v",*opts.sizePtr)}}func(opts*Avatarme)Generate(){opts.SetOpts()c:=[3]uint8{}hash:=[]byte{}text:=opts.inputshashAlg:=*opts.hashAlgPtr// get hashswitchhashAlg{caseSHA1:_a:=sha1.Sum([]byte(text))hash=_a[:sha1.Size]caseSHA224:_a:=sha256.Sum224([]byte(text))hash=_a[:sha256.Size224]caseSHA256:_a:=sha256.Sum256([]byte(text))hash=_a[:sha256.Size]caseSHA384:_a:=sha512.Sum384([]byte(text))hash=_a[:sha512.Size384]caseSHA512:_a:=sha512.Sum512([]byte(text))hash=_a[:sha512.Size]}// select color (first 3 hash value)copy(c[:],hash[:3])colorrgb:=color.RGBA{c[0],c[1],c[2],0xff}// R, G, B, Alpha// create .pngoutFile,err:=os.Create("avatarme.png")iferr!=nil{log.Fatal(err)}deferoutFile.Close()// size is mutltiple of 5size:=int(math.Ceil(float64(*opts.sizePtr)/float64(mutltiple)))*mutltipleblockSize:=size/mutltipleimg:=image.NewRGBA(image.Rect(0,0,size,size))// x1,y1, x2,y2whiteColor:=color.RGBA{0xff,0xff,0xff,0xff}// R, G, B, Alpha// backfill entire surface with whitedraw.Draw(img,img.Bounds(),&image.Uniform{whiteColor},image.ZP,draw.Src)hashLen:=len(hash)// choose first 25 bytesfori:=0;i<(mutltiple*numberHash);i+=numberHash{hashIndex:=i%hashLenchunks:=[]byte{}ifhashIndex+numberHash<hashLen{chunks=append(chunks,hash[hashIndex:hashIndex+3]...)}else{rest:=(hashIndex+numberHash)-hashLenchunks=append(chunks,hash[hashIndex:hashLen]...)chunks=append(chunks,hash[0:rest]...)}chunks=append(chunks,chunks[1:2]...)chunks=append(chunks,chunks[0:1]...)origin:=i/numberHash*mutltipleforindex:=origin;index<origin+mutltiple;index+=1{// filter out even numberifchunks[index-origin]%2==1{continue}horizontal:=(index%mutltiple)*blockSizevertical:=(index/mutltiple)*blockSizeblock:=image.Rect(horizontal,vertical,horizontal+blockSize,vertical+blockSize)// geometry of 2nd rectangledraw.Draw(img,block,&image.Uniform{colorrgb},image.ZP,draw.Src)}}png.Encode(outFile,img)}
Reference
Top comments(1)
Subscribe
For further actions, you may consider blocking this person and/orreporting abuse