uuidtools.rb

来自「用ruby on rails写的一个博客程序,还不错..ruby on rail」· RB 代码 · 共 555 行 · 第 1/2 页

RB
555
字号
#--# Copyright (c) 2005 Robert Aman## Permission is hereby granted, free of charge, to any person obtaining# a copy of this software and associated documentation files (the# "Software"), to deal in the Software without restriction, including# without limitation the rights to use, copy, modify, merge, publish,# distribute, sublicense, and/or sell copies of the Software, and to# permit persons to whom the Software is furnished to do so, subject to# the following conditions:## The above copyright notice and this permission notice shall be# included in all copies or substantial portions of the Software.## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.#++UUID_TOOLS_VERSION = "0.1.1"$:.unshift(File.dirname(__FILE__))require 'uri'require 'time'require 'thread'require 'digest/sha1'require 'digest/md5'#  Because it's impossible to hype a UUID generator on its genuine merits,#  I give you... Really bad ASCII art in the comments:##                                                                  #                \                                                 #                /                                                   #               +                                                  #              ]                                                   #              ]                                                   #              |                                                    #             /                                                     #           Mp___                                                  #              `~0NNp,                                             #               __ggM'                                             #             g0M~"`                                               #            ]0M*-                                                 #                                                                  #                    ___                                           #                _g000M00g,                                        #              j0M~      ~M&                                       #            j0M"          ~N,                                     #           j0P              M&                                    #          jM                  1                                   #         j0                   ]1                                  #        .0P                    0,                                 #        00'                    M&                                 #        0M                     ]0L                                #       ]0f         ___          M0                                #        M0NN0M00MMM~"'M          0&                               #          `~          ~0         ]0,                              #                       ]M        ]0&                              #                        M&        M0,                             #               ____gp_   M&        M0_                            #            __p0MPM8MM&_  M/        ^0&_                          #           gN"`       M0N_j0,         MM&__                       #         _gF           `~M0P`   __      M00g                      #        g0'                    gM0&,     ~M0&                     #      _pM`                     0, ]M1     "00&                    #     _00                    /g1MMgj01      ]0MI                   #    _0F                     t"M,7MMM        00I                   #   g0'                  _   N&j&            40'                   #  g0'                _p0Mq_   '             N0QQNM#g,             #  0'              _g0000000g__              ~M@MMM000g            #  f             _jM00@`  ~M0000Mgppg,             "P00&           # |             g000~       `~M000000&_               ~0&          # ]M          _M00F              "00MM`                ~#&         # `0L        m000F                #E                    "0f        #   9r     j000M`                 40,                    00        #    ]0g_ j00M`                   ^M0MNggp#gqpg          M0&       #     ~MPM0f                         ~M000000000g_ ,_ygg&M00f      #                                        `~~~M00000000000000       #                                              `M0000000000f       #                                                  ~@@@MF~`        #                                                                  #                                                                  #= uuidtools.rb## UUIDTools was designed to be a simple library for generating any# of the various types of UUIDs.  It conforms to RFC 4122 whenever# possible.##== Example#  UUID.md5_create(UUID_DNS_NAMESPACE, "www.widgets.com")#  => #<UUID:0x287576 UUID:3d813cbb-47fb-32ba-91df-831e1593ac29>#  UUID.sha1_create(UUID_DNS_NAMESPACE, "www.widgets.com")#  => #<UUID:0x2a0116 UUID:21f7f8de-8051-5b89-8680-0195ef798b6a>#  UUID.timestamp_create#  => #<UUID:0x2adfdc UUID:64a5189c-25b3-11da-a97b-00c04fd430c8>#  UUID.random_create#  => #<UUID:0x19013a UUID:984265dc-4200-4f02-ae70-fe4f48964159>class UUID  @@last_timestamp = nil  @@last_node_id = nil  @@last_clock_sequence = nil  @@state_file = nil  @@mutex = Mutex.new    def initialize(time_low, time_mid, time_hi_and_version,      clock_seq_hi_and_reserved, clock_seq_low, nodes)    unless time_low >= 0 && time_low < 4294967296      raise ArgumentError,        "Expected unsigned 32-bit number for time_low, got #{time_low}."    end    unless time_mid >= 0 && time_mid < 65536      raise ArgumentError,        "Expected unsigned 16-bit number for time_mid, got #{time_mid}."    end    unless time_hi_and_version >= 0 && time_hi_and_version < 65536      raise ArgumentError,        "Expected unsigned 16-bit number for time_hi_and_version, " +        "got #{time_hi_and_version}."    end    unless clock_seq_hi_and_reserved >= 0 && clock_seq_hi_and_reserved < 256      raise ArgumentError,        "Expected unsigned 8-bit number for clock_seq_hi_and_reserved, " +        "got #{clock_seq_hi_and_reserved}."    end    unless clock_seq_low >= 0 && clock_seq_low < 256      raise ArgumentError,        "Expected unsigned 8-bit number for clock_seq_low, " +        "got #{clock_seq_low}."    end    unless nodes.respond_to? :size      raise ArgumentError,        "Expected nodes to respond to :size."    end      unless nodes.size == 6      raise ArgumentError,        "Expected nodes to have size of 6."    end    for node in nodes      unless node >= 0 && node < 256        raise ArgumentError,          "Expected unsigned 8-bit number for each node, " +          "got #{node}."      end    end    @time_low = time_low    @time_mid = time_mid    @time_hi_and_version = time_hi_and_version    @clock_seq_hi_and_reserved = clock_seq_hi_and_reserved    @clock_seq_low = clock_seq_low    @nodes = nodes  end    attr_accessor :time_low  attr_accessor :time_mid  attr_accessor :time_hi_and_version  attr_accessor :clock_seq_hi_and_reserved  attr_accessor :clock_seq_low  attr_accessor :nodes    # Parses a UUID from a string.  def UUID.parse(uuid_string)    unless uuid_string.kind_of? String      raise ArgumentError,        "Expected String, got #{uuid_string.class.name} instead."    end    uuid_components = uuid_string.downcase.scan(      Regexp.new("^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-" +        "([0-9a-f]{2})([0-9a-f]{2})-([0-9a-f]{12})$")).first    raise ArgumentError, "Invalid UUID format." if uuid_components.nil?    time_low = uuid_components[0].to_i(16)    time_mid = uuid_components[1].to_i(16)    time_hi_and_version = uuid_components[2].to_i(16)    clock_seq_hi_and_reserved = uuid_components[3].to_i(16)    clock_seq_low = uuid_components[4].to_i(16)    nodes = []    for i in 0..5      nodes << uuid_components[5][(i * 2)..(i * 2) + 1].to_i(16)    end    return UUID.new(time_low, time_mid, time_hi_and_version,      clock_seq_hi_and_reserved, clock_seq_low, nodes)  end  # Parses a UUID from a raw byte string.  def UUID.parse_raw(raw_string)    unless raw_string.kind_of? String      raise ArgumentError,        "Expected String, got #{raw_string.class.name} instead."    end    integer = UUID.convert_byte_string_to_int(raw_string)    time_low = (integer >> 96) & 0xFFFFFFFF    time_mid = (integer >> 80) & 0xFFFF    time_hi_and_version = (integer >> 64) & 0xFFFF    clock_seq_hi_and_reserved = (integer >> 56) & 0xFF    clock_seq_low = (integer >> 48) & 0xFF    nodes = []    for i in 0..5      nodes << ((integer >> (40 - (i * 8))) & 0xFF)    end    return UUID.new(time_low, time_mid, time_hi_and_version,      clock_seq_hi_and_reserved, clock_seq_low, nodes)  end  # Creates a UUID from a random value.  def UUID.random_create()    new_uuid = UUID.parse_raw(UUID.true_random)    new_uuid.time_hi_and_version &= 0x0FFF    new_uuid.time_hi_and_version |= (4 << 12)    new_uuid.clock_seq_hi_and_reserved &= 0x3F    new_uuid.clock_seq_hi_and_reserved |= 0x80    return new_uuid  end  # Creates a UUID from a timestamp.  def UUID.timestamp_create(timestamp=nil)    # We need a lock here to prevent two threads from ever    # getting the same timestamp.    @@mutex.synchronize do      # Always use GMT to generate UUIDs.      gmt_timestamp = Time.now.gmtime      # Convert to 100 nanosecond blocks      gmt_timestamp_100_nanoseconds = (gmt_timestamp.tv_sec * 10000000) +        (gmt_timestamp.tv_usec * 10) + 0x01B21DD213814000      nodes = UUID.get_mac_address.split(":").collect do |octet|        octet.to_i(16)      end      node_id = 0      for i in 0..5        node_id += (nodes[i] << (40 - (i * 8)))      end      clock_sequence = @@last_clock_sequence      if clock_sequence.nil?        clock_sequence = UUID.convert_byte_string_to_int(UUID.true_random)      end      if @@last_node_id != nil && @@last_node_id != node_id        # The node id has changed.  Change the clock id.        clock_sequence = UUID.convert_byte_string_to_int(UUID.true_random)      elsif @@last_timestamp != nil &&          gmt_timestamp_100_nanoseconds < @@last_timestamp        clock_sequence = clock_sequence + 1      end      @@last_timestamp = gmt_timestamp_100_nanoseconds      @@last_node_id = node_id      @@last_clock_sequence = clock_sequence      time_low = gmt_timestamp_100_nanoseconds & 0xFFFFFFFF      time_mid = ((gmt_timestamp_100_nanoseconds >> 32) & 0xFFFF)      time_hi_and_version = ((gmt_timestamp_100_nanoseconds >> 48) & 0x0FFF)      time_hi_and_version |= (1 << 12)      clock_seq_low = clock_sequence & 0xFF;      clock_seq_hi_and_reserved = (clock_sequence & 0x3F00) >> 8      clock_seq_hi_and_reserved |= 0x80            return UUID.new(time_low, time_mid, time_hi_and_version,        clock_seq_hi_and_reserved, clock_seq_low, nodes)    end  end  # Creates a UUID using the MD5 hash.  (Version 3)  def UUID.md5_create(namespace, name)    return UUID.create_from_hash(Digest::MD5, namespace, name)  end    # Creates a UUID using the SHA1 hash.  (Version 5)  def UUID.sha1_create(namespace, name)    return UUID.create_from_hash(Digest::SHA1, namespace, name)  end    # This method applies only to version 1 UUIDs.  # Checks if the node ID was generated from a random number  # or from an IEEE 802 address (MAC address).

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?