# Elisp: Insert Random UUID

By Xah Lee. Date: . Last updated: .

This week's exercise is to write a function `insert-random-uuid`. When called, it should insert a UUID. Here's some examples of UUID:

```0a1cd3bc-96fa-71d1-4338-27092ca4cfa5
1e27a053-60a4-af61-f38d-9f1f123740d6
115024d2-7c74-326e-c9ec-064f42d08b31
070f1f0b-2454-3ffa-4aa2-d6e0652d03fe```

Basically, it's a random string of symbols 0 to 9 and a to f, arranged in 8-4-4-4-12 blocks. There are many ways to implement this.

## Solution

Here's a sloppy toy solution that gets the idea across:

```(random t)

(defun insert-random-uuid ()
"Insert a random UUID.
Example of a UUID: 1df63142-a513-c850-31a3-535fc3520c3d

WARNING: this is a simple implementation. The chance of generating the same UUID is much higher than a robust algorithm.."
(interactive)
(insert
(format "%04x%04x-%04x-%04x-%04x-%06x%06x"
(random (expt 16 4))
(random (expt 16 4))
(random (expt 16 4))
(random (expt 16 4))
(random (expt 16 4))
(random (expt 16 6))
(random (expt 16 6)) ) ) )```

Elisp's `random` function can be called in 3 ways:

• `(random t)`. Set a random seed based on current time and PID (process ID).
• `(random n)`. Returns a random number between 0 and `n-1`, including possible `0` and `n-1`.
• `(random)`. Returns a random number between 0 and 2^29-1, inclusive.

Elisp's documentation does not say exactly how large a pool the random number is generated from, only that “On most systems, this is 29 bits' worth.”. (See: (info "(elisp) Random Numbers"))

UUID is basically a random number between 0 and 2^128-1, inclusive. Since emacs's random is only from a space of 2^29 possibilities, so we need to call it several times.

Note: if you don't know already, the random number generating function in almost all computer languages are called Pseudorandom number generator. They are numbers generated in a predictive way. For example, if you start emacs, then if you call `(random 100)` few times, you will always get this sequence: {0 38 17 70 …}. (For this to work, make sure none of your init files calls `(random t)`. (start emacs by `emacs -Q` to prevent loading any init files).)

It's a good idea to set a seed when you Alt+x `random` in elisp, and the setting of seed should be outside of your function.

The meaning of randomness is a deep math topic. In general, there is no one absolute universal definition. You might check relevant articles on Wikipedia, starting with Random sequence.

### Using MD5 to Generate UUID

Here's a better solution, by Christopher Wellons.

```(defun xah-insert-random-uuid ()
"Insert a UUID. This uses a simple hashing of variable data.
Example of a UUID: 1df63142-a513-c850-31a3-535fc3520c3d

Note: this code uses https://en.wikipedia.org/wiki/Md5 , which is not cryptographically safe. I'm not sure what's the implication of its use here.

Version 2015-01-30
URL `http://ergoemacs.org/emacs/elisp_generate_uuid.html'
"
;; by Christopher Wellons, 2011-11-18. Editted by Xah Lee.
;; Edited by Hideki Saito further to generate all valid variants for "N" in xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx format.
(interactive)
(let ((myStr (md5 (format "%s%s%s%s%s%s%s%s%s%s"
(user-uid)
(emacs-pid)
(system-name)
(user-full-name)
(current-time)
(emacs-uptime)
(garbage-collect)
(buffer-string)
(random)
(recent-keys)))))

(insert (format "%s-%s-4%s-%s%s-%s"
(substring myStr 0 8)
(substring myStr 8 12)
(substring myStr 13 16)
(format "%x" (+ 8 (random 4)))
(substring myStr 17 20)
(substring myStr 20 32)))))```

It uses several random elements from emacs, then Alt+x `md5` to generate the UUID.

## Robust Implementation of UUID

Note, according to Wikipedia's description of UUID, in the “Variants and Versions” section, some digits should be fixed when the UUID is generated by a random or pseudo-random number.

That is, in the format: `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`

The “M” should be “4” and the N should be one of {8, 9, A, B}.

### Call Linux Shell 「uuidgen」

Linux has a shell command “uuidgen”. You can write a elisp wrapper to call it, like this:

```(defun insert-random-uuid ()
(interactive)
(shell-command "uuidgen" t))```

See also: Windows CLSID Explained

Thanks to [Yuri Khan https://plus.google.com/+YuriKhan/posts] and Jon Snader http://irreal.org/blog/ for discussion about UUID.

Thanks to Christopher Wellons http://nullprogram.com/ and Hideki Saito http://hideki.hclippr.com/2014/02/02/on-generating-uuid/

#### Elisp Command to Insert Things

If you have a question, put \$5 at patreon and message me.
Or Buy Xah Emacs Tutorial
Or buy a nice keyboard: Best Keyboards for Emacs