Skip to content

Instantly share code, notes, and snippets.

@Deepwalker
Created January 10, 2013 09:50
Show Gist options
  • Save Deepwalker/4500836 to your computer and use it in GitHub Desktop.
Save Deepwalker/4500836 to your computer and use it in GitHub Desktop.
require 'macaddr'
module AngryUID
# TODO Now we dont resolve time problems - if
# we move time to past, then bad things can happen
class UID
CLOCK_MULTIPLIER = 10_000_000 # 10ns
# Arrange
# -------
# tt tt tt tt tt tt tt _ ss __ pp pp _ mm mm mm mm mm mm
# tt - time with 10ns precision, 7 bytes
# ss - sequence number (not used now), 1 byte
# pp - pid, 2 bytes
# mm - mac address, 6 bytes
def initialize
@mac_addr = mac_address
@pid = Process.pid
@base = (@pid << (6 * 8)) + @mac_addr
@seq = 0
@last_time = 0
end
def time
(Time.now.to_f * CLOCK_MULTIPLIER).to_i
end
def generate
new_time = time
if new_time <= @last_time
raise 'Pizdec blya'
end
@last_time = new_time
(new_time << (9 * 8)) + @base + (@seq << 8 * 8)
end
def hex
generate.to_s(16)
end
# From `uuid` gem.
# ##
# # Generate a pseudo MAC address because we have no pure-ruby way
# # to know the MAC address of the NIC this system uses. Note
# # that cheating with pseudo arresses here is completely legal:
# # see Section 4.5 of RFC4122 for details.
# #
# # This implementation is shamelessly stolen from
# # https://github.com/spectra/ruby-uuid/blob/master/uuid.rb
# # Thanks spectra.
# #
def mac_address
iee_mac_address || pseudo_mac_address
end
def iee_mac_address
begin
Mac.addr.gsub(/:|-/, '').hex & 0x7FFFFFFFFFFF
rescue
nil
end
end
def pseudo_mac_address
sha1 = ::Digest::SHA1.new
256.times do
r = [rand(0x100000000)].pack "N"
sha1.update r
end
str = sha1.digest
r = rand 14 # 20-6
node = str[r, 6] || str
if RUBY_VERSION >= "1.9.0"
nnode = node.bytes.to_a
nnode[0] |= 0x01
node = ''
nnode.each { |s| node << s.chr }
else
node[0] |= 0x01 # multicast bit
end
node.bytes.collect{|b|b.to_s(16)}.join.hex & 0x7FFFFFFFFFFF
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment