Emacs UUIDs
Yesterday Luke pointed out an interesting idea by Jeff Atwood: mark code snippets you post online with a UUID. That way it's easy to find other places where code snippets have been used, and it's easier to find updates. It's a neat idea that I might start using.
So, the next problem is where to get a UUID. One place to get one is createguid.com, which will serve you up a fresh version 4 UUID each visit. But I don't like relying on the Internet for something when I don't need to. This is why I sometimes make wget backups of my favorite sites, in case they ever disappear. By design it's easy to generate your own UUIDs, and you have 5 algorithms to choose from, so I'll make my own.
Since I'll always be in Emacs when I need one, I'll just have Emacs do
it. However, it's a bit tricky to do in Emacs. The pseudo-random
number generator isn't very good. It's always initialized to the same
seed when it starts, so it's up to the user to reseed
somewhere. There's no direct way to read
from /dev/urandom, instead relying on an external process
to feed it in. Relying on /dev/urandom is also not
portable. There's also no simple, portable way to find out hardware
information about the machine, such as MAC address, required by some
versions of the UUID algorithms. Elisp integers are a few bits smaller
than native integers (29-bits on 32-bit systems), so the UUID has to
be handled in very small pieces.
I was beginning to work on my own when I found
this
great solution by Martin Blais
(mirror). Specifically
the uuid-simple function, which takes an MD5 hash of
unique data in Emacs and uses it for the UUID. I believe this may
count as a version 3 UUID (or at least close enough that I don't
care). I modified it slightly, adding more unique data and a version
number.
;; ID: 90aebf38-b33a-314b-1198-c9bffea2f2a2
(defun uuid-create ()
"Return a newly generated UUID. This uses a simple hashing of variable data."
(let ((s (md5 (format "%s%s%s%s%s%s%s%s%s%s"
(user-uid)
(emacs-pid)
(system-name)
(user-full-name)
user-mail-address
(current-time)
(emacs-uptime)
(garbage-collect)
(random)
(recent-keys)))))
(format "%s-%s-3%s-%s-%s"
(substring s 0 8)
(substring s 8 12)
(substring s 13 16)
(substring s 16 20)
(substring s 20 32))))
This returns a string containing the UUID. Next, make an interactive function to wrap it,
(defun uuid-insert ()
"Inserts a new UUID at the point."
(interactive)
(insert (uuid-create)))
I bound this to "C-x !", which wasn't yet bound to
anything.
(global-set-key <span class="string">"\C-x!"</span> 'uuid-insert)
Instant UUIDs in Emacs.
blog comments powered by Disqus