From ec66213424e671c70d1d8dd3675b85ae24d10e5f Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 2 May 2018 22:32:07 -0700 Subject: Add uuidgen. Reuse create_uuid, but make it match the current RFC. --- lib/lib.c | 23 ++++++++--------------- tests/uuidgen.test | 7 +++++++ toys/pending/uuidgen.c | 25 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 15 deletions(-) create mode 100755 tests/uuidgen.test create mode 100644 toys/pending/uuidgen.c diff --git a/lib/lib.c b/lib/lib.c index 8c46678f..3bfe7fc4 100644 --- a/lib/lib.c +++ b/lib/lib.c @@ -1138,29 +1138,22 @@ int qstrcmp(const void *a, const void *b) return strcmp(*(char **)a, *(char **)b); } -// According to http://www.opengroup.org/onlinepubs/9629399/apdxa.htm -// we should generate a uuid structure by reading a clock with 100 nanosecond -// precision, normalizing it to the start of the gregorian calendar in 1582, -// and looking up our eth0 mac address. -// -// On the other hand, we have 128 bits to come up with a unique identifier, of -// which 6 have a defined value. /dev/urandom it is. - +// See https://tools.ietf.org/html/rfc4122, specifically section 4.4 +// "Algorithms for Creating a UUID from Truly Random or Pseudo-Random +// Numbers". void create_uuid(char *uuid) { - // Read 128 random bits + // "Set all the ... bits to randomly (or pseudo-randomly) chosen values". int fd = xopenro("/dev/urandom"); xreadall(fd, uuid, 16); close(fd); - // Claim to be a DCE format UUID. + // "Set the four most significant bits ... of the time_hi_and_version + // field to the 4-bit version number [4]". uuid[6] = (uuid[6] & 0x0F) | 0x40; + // "Set the two most significant bits (bits 6 and 7) of + // clock_seq_hi_and_reserved to zero and one, respectively". uuid[8] = (uuid[8] & 0x3F) | 0x80; - - // rfc2518 section 6.4.1 suggests if we're not using a macaddr, we should - // set bit 1 of the node ID, which is the mac multicast bit. This means we - // should never collide with anybody actually using a macaddr. - uuid[11] |= 128; } char *show_uuid(char *uuid) diff --git a/tests/uuidgen.test b/tests/uuidgen.test new file mode 100755 index 00000000..2042a4b9 --- /dev/null +++ b/tests/uuidgen.test @@ -0,0 +1,7 @@ +#!/bin/bash + +[ -f testing.sh ] && . testing.sh + +#testing "name" "command" "result" "infile" "stdin" + +testing "smoke" "uuidgen | grep -Eq '[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}' && echo okay" "okay\n" "" "" diff --git a/toys/pending/uuidgen.c b/toys/pending/uuidgen.c new file mode 100644 index 00000000..682dec4c --- /dev/null +++ b/toys/pending/uuidgen.c @@ -0,0 +1,25 @@ +/* uuidgen.c - Create a new random UUID + * + * Copyright 2018 The Android Open Source Project + * + * UUID RFC: https://tools.ietf.org/html/rfc4122 + +USE_UUIDGEN(NEWTOY(uuidgen, ">0r(random)", TOYFLAG_USR|TOYFLAG_BIN)) + +config UUIDGEN + bool "uuidgen" + default n + help + usage: uuidgen + + Create and print a new RFC4122 random UUID. +*/ + +#define FOR_uuidgen +#include "toys.h" + +void uuidgen_main(void) +{ + create_uuid(toybuf); + puts(show_uuid(toybuf)); +} -- cgit v1.2.3