Skip to content

Commit 0b03ecb

Browse files
committed
It works.
0 parents  commit 0b03ecb

File tree

7 files changed

+403
-0
lines changed

7 files changed

+403
-0
lines changed

.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Binaries for programs and plugins
2+
*.exe
3+
*.exe~
4+
*.dll
5+
*.so
6+
*.dylib
7+
8+
# Test binary, built with `go test -c`
9+
*.test
10+
11+
# Output of the go coverage tool, specifically when used with LiteIDE
12+
*.out
13+
14+
# Dependency directories (remove the comment below to include it)
15+
# vendor/
16+

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 2021
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# stellar-identicon-go

color.go

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package identicon
2+
3+
import "math"
4+
5+
type HSV struct {
6+
H, S, V float64
7+
}
8+
9+
type RGB struct {
10+
R, G, B float64
11+
}
12+
13+
func (c *HSV) RGB() *RGB {
14+
var r, g, b float64
15+
if c.S == 0 {
16+
r = c.V * 255
17+
g = c.V * 255
18+
b = c.V * 255
19+
} else {
20+
h := c.H * 6
21+
if h == 6 {
22+
h = 0
23+
}
24+
i := math.Floor(h)
25+
v1 := c.V * (1 - c.S)
26+
v2 := c.V * (1 - c.S*(h-i))
27+
v3 := c.V * (1 - c.S*(1-(h-i)))
28+
29+
switch i {
30+
case 0:
31+
r = c.V
32+
g = v3
33+
b = v1
34+
case 1:
35+
r = v2
36+
g = c.V
37+
b = v1
38+
case 2:
39+
r = v1
40+
g = c.V
41+
b = v3
42+
case 3:
43+
r = v3
44+
g = v1
45+
b = c.V
46+
default:
47+
r = c.V
48+
g = v1
49+
b = v2
50+
}
51+
52+
r = r * 255
53+
g = g * 255
54+
b = b * 255
55+
}
56+
rgb := &RGB{r, g, b}
57+
return rgb
58+
}

go.mod

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/overcat/stellar-identicon-go
2+
3+
go 1.16
4+
5+
require github.com/stellar/go v0.0.0-20210311180751-e33a4571b3e9

go.sum

+209
Large diffs are not rendered by default.

identicon.go

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Package stellar_identicon provides a way to generate identicons for Stellar accounts.
2+
package identicon
3+
4+
import (
5+
"encoding/base32"
6+
"errors"
7+
"github.com/stellar/go/strkey"
8+
"image"
9+
"image/color"
10+
"math"
11+
)
12+
13+
const (
14+
// Default width of resulting identicon image in pixels
15+
Width = 210
16+
// Default height of resulting identicon image in pixels
17+
Height = 210
18+
)
19+
20+
const (
21+
columns = 7
22+
rows = 7
23+
)
24+
25+
// This exception will be thrown when an invalid address is used
26+
var InvalidEd25519PublicKeyError = errors.New("invalid ed25519 public key")
27+
28+
// Generates an identicon for the given stellar address
29+
func Generate(publicKey string, width, height int) (*image.RGBA, error) {
30+
if !strkey.IsValidEd25519PublicKey(publicKey) {
31+
return nil, InvalidEd25519PublicKeyError
32+
}
33+
34+
keyData, err := base32.StdEncoding.DecodeString(publicKey)
35+
if err != nil {
36+
return nil, err
37+
}
38+
39+
keyData = keyData[2:]
40+
41+
var matrix [7][7]bool
42+
43+
columnsForCalculation := int(math.Ceil(columns / 2.0))
44+
for column := 0; column < columnsForCalculation; column++ {
45+
for row := 0; row < rows; row++ {
46+
if getBit(column+row*columnsForCalculation, keyData[1:]) {
47+
matrix[row][column] = true
48+
matrix[row][columns-column-1] = true
49+
}
50+
}
51+
}
52+
53+
img := image.NewRGBA(image.Rect(0, 0, width, height))
54+
foreground := getColor(keyData)
55+
blockWidth := width / columns
56+
blockHeight := height / rows
57+
58+
for row, rowColumns := range matrix {
59+
for column, cell := range rowColumns {
60+
if cell {
61+
x0 := column * blockWidth
62+
y0 := row * blockHeight
63+
x1 := (column+1)*blockWidth - 1
64+
y1 := (row+1)*blockHeight - 1
65+
for x := x0; x <= x1; x++ {
66+
for y := y0; y <= y1; y++ {
67+
img.Set(x, y, foreground)
68+
}
69+
}
70+
}
71+
}
72+
}
73+
return img, nil
74+
}
75+
76+
func getColor(data []byte) color.RGBA {
77+
hsv := HSV{
78+
H: float64(data[0]) / 255,
79+
S: 0.7,
80+
V: 0.8,
81+
}
82+
rgb := hsv.RGB()
83+
return color.RGBA{
84+
R: uint8(rgb.R), G: uint8(rgb.G), B: uint8(rgb.B), A: 255,
85+
}
86+
}
87+
88+
func getBit(n int, keyData []byte) bool {
89+
if keyData[n/8]>>(8-((n%8)+1))&1 == 1 {
90+
return true
91+
}
92+
return false
93+
}

0 commit comments

Comments
 (0)