status-im/status-go

View on GitHub
protocol/identity/identicon/identicon.go

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
package identicon

import (
    "crypto/md5" // nolint: gosec
    "image/color"

    "github.com/lucasb-eyer/go-colorful"
)

const (
    defaultSaturation = 0.5
    defaultLightness  = 0.7
)

type Identicon struct {
    bitmap []byte
    color  color.Color
}

func generate(key string) Identicon {
    hash := md5.Sum([]byte(key)) // nolint: gosec
    return Identicon{
        convertPatternToBinarySwitch(generatePatternFromHash(hash)),
        getColorFromHash(hash),
    }
}

func getColorFromHash(h [16]byte) color.Color {
    // Take the last 3 relevant bytes, and convert to a float between [0..360]
    sum := float64(h[13]) + float64(h[14]) + float64(h[15])
    t := (sum / 765) * 360
    return colorful.Hsl(t, defaultSaturation, defaultLightness)
}

func generatePatternFromHash(sum [16]byte) []byte {
    p := make([]byte, 25)
    for i := 0; i < 5; i++ {
        for j := 0; j < 5; j++ {
            jCount := j

            if j > 2 {
                jCount = 4 - j
            }

            p[5*i+j] = sum[3*i+jCount]
        }
    }
    return p
}

func convertPatternToBinarySwitch(pattern []byte) []byte {
    b := make([]byte, 25)
    for i, v := range pattern {
        if v%2 == 0 {
            b[i] = 1
        } else {
            b[i] = 0
        }
    }
    return b
}