module RubyIdenticon

A Ruby implementation of go-identicon

RubyIdenticon creates an Identicon, similar to those created by Github.

A title and key are used by siphash to calculate a hash value that is then used to create a visual identicon representation.

The identicon is made by creating a left hand side pixel representation of each bit in the hash value - this is then mirrored onto the right hand side to create an image that we see as a shape.

The grid and square sizes can be varied to create identicons of differing size.

Constants

DEFAULT_OPTIONS

the default options used when creating identicons

background_color: (Integer, default 0) the background color of the identicon in rgba notation (e.g. xffffffff for white) border_size: (Integer, default 35) the size in pixels to leave as an empty border around the identicon image grid_size: (Integer, default 7) the number of rows and columns in the identicon, minimum 4, maximum 9 square_size: (Integer, default 50) the size in pixels of each square that makes up the identicon key: (String) a 16 byte key used by siphash when calculating the hash value (see note below)

varying the key ensures uniqueness of an identicon for a given title, it is assumed desirable for different applications to use a different key.

VERSION

Public Class Methods

create(title, options = {}) click to toggle source

create an identicon png and return it as a binary string

Example:

>> RubyIdenticon.create('identicons are great!')
=> binary blob (String)

@param title [string] the string value to be represented as an identicon @param options [hash] additional options for the identicon

# File lib/ruby_identicon.rb, line 96
def self.create(title, options = {})
  options = DEFAULT_OPTIONS.merge(options)

  raise 'title cannot be nil' if title == nil
  raise 'key is nil or less than 16 bytes' if options[:key] == nil || options[:key].length < 16
  raise 'grid_size must be between 4 and 9' if options[:grid_size] < 4 || options[:grid_size] > 9
  raise 'invalid border size' if options[:border_size] < 0
  raise 'invalid square size' if options[:square_size] < 0

  hash = SipHash.digest(options[:key], title)

  png = ChunkyPNG::Image.new((options[:border_size] * 2) + (options[:square_size] * options[:grid_size]),
   (options[:border_size] * 2) + (options[:square_size] * options[:grid_size]), options[:background_color])

  # set the foreground color by using the first three bytes of the hash value
  color = ChunkyPNG::Color.rgba((hash & 0xff), ((hash >> 8) & 0xff), ((hash >> 16) & 0xff), 0xff)

  # remove the first three bytes that were used for the foreground color
  hash >>= 24

  sqx = sqy = 0
  (options[:grid_size] * ((options[:grid_size] + 1) / 2)).times do
    if hash & 1 == 1
      x = options[:border_size] + (sqx * options[:square_size])
      y = options[:border_size] + (sqy * options[:square_size])

      # left hand side
      png.rect(x, y, x + options[:square_size] - 1, y + options[:square_size] - 1, color, color)

      # mirror right hand side
      x = options[:border_size] + ((options[:grid_size] - 1 - sqx) * options[:square_size])
      png.rect(x, y, x + options[:square_size] - 1, y + options[:square_size] - 1, color, color)
    end

    hash >>= 1
    sqy += 1
    if sqy == options[:grid_size]
      sqy = 0
      sqx += 1
    end
  end

  png.to_blob color_mode: ChunkyPNG::COLOR_INDEXED
end
create_and_save(title, filename, options = {}) click to toggle source

create an identicon png and save it to the given filename

Example:

>> RubyIdenticon.create_and_save('identicons are great!', 'test_identicon.png')
=> result (Boolean)

@param title [string] the string value to be represented as an identicon @param filename [string] the full path and filename to save the identicon png to @param options [hash] additional options for the identicon

# File lib/ruby_identicon.rb, line 78
def self.create_and_save(title, filename, options = {})
  raise 'filename cannot be nil' if filename == nil

  blob = create(title, options)
  return false if blob == nil

  File.open(filename, 'wb') { |f| f.write(blob) }
end
create_base64(title, options = {}) click to toggle source
# File lib/ruby_identicon.rb, line 141
def self.create_base64(title, options = {})
  Base64.encode64(self.create(title, options)).force_encoding('UTF-8')
end