Software /
code /
prosody
Comparison
util/uuid.lua @ 7057:c633e1338554
util.uuid: Use /dev/urandom
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 06 Jan 2016 02:46:47 +0100 |
parent | 7010:001b3cff4ed8 |
child | 7061:eda0feeaf759 |
child | 7076:ad9e683b8f0b |
comparison
equal
deleted
inserted
replaced
7056:7b0651e4534f | 7057:c633e1338554 |
---|---|
4 -- | 4 -- |
5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
7 -- | 7 -- |
8 | 8 |
9 | 9 local error = error; |
10 local tostring = tostring; | 10 local round_up = math.ceil; |
11 local os_time = os.time; | 11 local urandom, urandom_err = io.open("/dev/urandom", "r+"); |
12 local os_clock = os.clock; | |
13 local sha1 = require "util.hashes".sha1; | |
14 | 12 |
15 module "uuid" | 13 module "uuid" |
16 | 14 |
17 local last_uniq_time = 0; | |
18 local function uniq_time() | |
19 local new_uniq_time = os_time(); | |
20 if last_uniq_time >= new_uniq_time then new_uniq_time = last_uniq_time + 1; end | |
21 last_uniq_time = new_uniq_time; | |
22 return new_uniq_time; | |
23 end | |
24 | |
25 local function new_random(x) | |
26 return sha1(x..os_clock()..tostring({}), true); | |
27 end | |
28 | |
29 local buffer = new_random(uniq_time()); | |
30 local function _seed(x) | |
31 buffer = new_random(buffer..x); | |
32 end | |
33 local function get_nibbles(n) | 15 local function get_nibbles(n) |
34 if #buffer < n then _seed(uniq_time()); end | 16 local binary_random = urandom:read(round_up(n/2)); |
35 local r = buffer:sub(0, n); | 17 local hex_random = binary_random:gsub(".", |
36 buffer = buffer:sub(n+1); | 18 function (x) return ("%02x"):format(x:byte()) end); |
37 return r; | 19 return hex_random:sub(1, n); |
38 end | 20 end |
39 local function get_twobits() | 21 local function get_twobits() |
40 return ("%x"):format(get_nibbles(1):byte() % 4 + 8); | 22 return ("%x"):format(urandom:read(1):byte() % 4 + 8); |
41 end | 23 end |
42 | 24 |
43 function generate() | 25 function generate() |
26 if not urandom then | |
27 error("Unable to obtain a secure random number generator, please see https://prosody.im/doc/random ("..urandom_err..")"); | |
28 end | |
44 -- generate RFC 4122 complaint UUIDs (version 4 - random) | 29 -- generate RFC 4122 complaint UUIDs (version 4 - random) |
45 return get_nibbles(8).."-"..get_nibbles(4).."-4"..get_nibbles(3).."-"..(get_twobits())..get_nibbles(3).."-"..get_nibbles(12); | 30 return get_nibbles(8).."-"..get_nibbles(4).."-4"..get_nibbles(3).."-"..(get_twobits())..get_nibbles(3).."-"..get_nibbles(12); |
46 end | 31 end |
47 seed = _seed; | 32 |
33 function seed(x) | |
34 urandom:write(x); | |
35 urandom:flush(); | |
36 end | |
48 | 37 |
49 return _M; | 38 return _M; |