Module uuid

Copyright 2012 Rackspace (original), 2013-2021 Thijs Schreijer (modifications)

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

see http://www.ietf.org/rfc/rfc4122.txt

Note that this is not a true version 4 (random) UUID. Since os.time() precision is only 1 second, it would be hard to guarantee spacial uniqueness when two hosts generate a uuid after being seeded during the same second. This is solved by using the node field from a version 1 UUID. It represents the mac address.

28-apr-2013 modified by Thijs Schreijer from the original Rackspace code as a generic Lua module. Regarding the above mention on os.time(); the modifications use the socket.gettime() function from LuaSocket if available and hence reduce that problem (provided LuaSocket has been loaded before uuid).

Important: the random seed is a global piece of data. Hence setting it is an application level responsibility, libraries should never set it!

See this issue; https://github.com/Kong/kong/issues/478 It demonstrates the problem of using time as a random seed. Specifically when used from multiple processes. So make sure to seed only once, application wide. And to not have multiple processes do that simultaneously.

Functions

new (hwaddr) Creates a new uuid.
randomseed (seed) Improved randomseed function.
seed () Seeds the random generator.


Functions

new (hwaddr)

Creates a new uuid. Either provide a unique hex string, or make sure the random seed is properly set. The module table itself is a shortcut to this function, so my_uuid = uuid.new() equals my_uuid = uuid().

For proper use there are 3 options;

  1. first require luasocket, then call uuid.seed(), and request a uuid using no parameter, eg. my_uuid = uuid()
  2. use uuid without luasocket, set a random seed using uuid.randomseed(some_good_seed), and request a uuid using no parameter, eg. my_uuid = uuid()
  3. use uuid without luasocket, and request a uuid using an unique hex string, eg. my_uuid = uuid(my_networkcard_macaddress)

Parameters:

  • hwaddr (optional) string containing a unique hex value (e.g.: 00:0c:29:69:41:c6), to be used to compensate for the lesser math_random() function. Use a mac address for solid results. If omitted, a fully randomized uuid will be generated, but then you must ensure that the random seed is set properly!

Returns:

    a properly formatted uuid string

Usage:

    local uuid = require("uuid")
    print("here's a new uuid: ",uuid())
randomseed (seed)
Improved randomseed function. Lua 5.1 and 5.2 both truncate the seed given if it exceeds the integer range. If this happens, the seed will be 0 or 1 and all randomness will be gone (each application run will generate the same sequence of random numbers in that case). This improved version drops the most significant bits in those cases to get the seed within the proper range again.

Parameters:

  • seed the random seed to set (integer from 0 - 2^32, negative values will be made positive)

Returns:

    the (potentially modified) seed used

Usage:

    local socket = require("socket")  -- gettime() has higher precision than os.time()
    local uuid = require("uuid")
    -- see also example at uuid.seed()
    uuid.randomseed(socket.gettime()*10000)
    print("here's a new uuid: ",uuid())
seed ()
Seeds the random generator. It does so in 3 possible ways;

  1. if in ngx_lua, use ngx.time() + ngx.worker.pid() to ensure a unique seed for each worker. It should ideally be called from the init_worker context.
  2. use luasocket gettime() function, but it only does so when LuaSocket has been required already.
  3. use os.time(): this only offers resolution to one second (used when LuaSocket hasn't been loaded)

Important: the random seed is a global piece of data. Hence setting it is an application level responsibility, libraries should never set it!

Usage:

    local socket = require("socket")  -- gettime() has higher precision than os.time()
    -- LuaSocket loaded, so below line does the same as the example from randomseed()
    uuid.seed()
    print("here's a new uuid: ",uuid())
generated by LDoc 1.4.6 Last updated 2021-07-11 08:59:24