using the random generator from PDFTeX and package xintbinhex for hexadecimal conversions.
edit: I add a simpler no-package version. Still using pdfuniformdeviate.
I forgot to say that the uppercase letters are produced with catcode letter, they are the usual ones. (in case it matters at all...)
edit2: somehow I misread instructions and was producing only 28 hexadecimal digits. Fixed.
\documentclass{article}
\usepackage{xintbinhex}
\makeatletter
% there is a complication as we need to avoid stripping leading zeros...
% ... but I am going to use \xintDecToHex which does that.
%
\begingroup\catcode0 12
\gdef\@expand@and@gob {\expandafter\@gobble\romannumeral`^^@}
\endgroup
% this one is expandable
\newcommand*{\GUID}
{%
% Data 1: (8 Hex Digits)
% \pdfuniformdeviate will refuse higher than "7FFFFFFF
% \xintDecToHex wants tokens, hence \the\numexpr needed.
% generate five hex digits and gobble the first one (which will be 1)
\@expand@and@gob
\xintDecToHex {\the\numexpr "10000+\pdfuniformdeviate "FFFF\relax}%
% again for a total of 8 Hex Digits
\@expand@and@gob
\xintDecToHex {\the\numexpr "10000+\pdfuniformdeviate "FFFF\relax}-%
% Data 2: (4 Hex Digits)
\@expand@and@gob
\xintDecToHex {\the\numexpr "10000+\pdfuniformdeviate "FFFF\relax}-%
% Data 3: (4 Hex Digits, the first one a 4)
\xintDecToHex {\the\numexpr "4000+\pdfuniformdeviate "FFF\relax}-%
% Data 4: (16=4+12 Hex Digits, the first one 8, 9 , A or B)
\xintDecToHex {\the\numexpr "8000+\pdfuniformdeviate "4000\relax}-%
\@expand@and@gob
\xintDecToHex {\the\numexpr "1000000+\pdfuniformdeviate "FFFFFF\relax}%
\@expand@and@gob
\xintDecToHex {\the\numexpr "1000000+\pdfuniformdeviate "FFFFFF\relax}%
}
% side-note: if we used directly \pdfuniformdeviate in \xintDecToHex,
% we could do it this way
% \xintDecToHex {\pdfuniformdeviate "FFFF }% <-- space needed
% we don't do this above as \xintDecToHex trims leading zeros
\makeatother
% this one is not expandable
\newcommand*{\GUIDnx}[1][.]{\begingroup\ifx.#1\else
\pdfsetrandomseed #1\relax\fi \GUID\endgroup}
% this one is not expandable
\newcommand*{\GUIDset}[2][.]{\begingroup\ifx.#1\else
\pdfsetrandomseed #1\relax\fi \xdef#2{\GUID}\endgroup}
\begin{document}
\ttfamily
\GUID\par
\GUID\par
\GUID\par
\edef\foo{\GUID}\meaning\foo<-- end of macro\par
\edef\foo{\GUID}\meaning\foo<-- end of macro\par
\GUIDnx [0]\par
\GUIDset[0]\foo
\meaning\foo<-- end of macro\par
\GUIDnx [123456789]\par
\GUIDset[123456789]\foo
\meaning\foo<-- end of macro\par
\end{document}
%No package version
\documentclass{article}
\def\GUIDonedigit {\ifcase\pdfuniformdeviate 16\space\space
0\or 1\or 2\or 3%
\or 4\or 5\or 6\or 7%
\or 8\or 9\or A\or B%
\or C\or D\or E\else F\fi}
\def\GUIDonespecialdigit {\ifcase\pdfuniformdeviate 4\space\space
8\or 9\or A\else B\fi }
% this one is expandable
\newcommand*{\GUID}
{%
% Data 1: (8 Hex Digits)
\GUIDonedigit\GUIDonedigit\GUIDonedigit\GUIDonedigit
\GUIDonedigit\GUIDonedigit\GUIDonedigit\GUIDonedigit-%
% Data 2: (4 Hex Digits)
\GUIDonedigit\GUIDonedigit\GUIDonedigit\GUIDonedigit-%
% Data 3 : (4 Hex Digits, the first one a 4)
4\GUIDonedigit\GUIDonedigit\GUIDonedigit-%
% Data 4: (16=4+12 Hex Digits, the first one 8, 9 , A or B)
\GUIDonespecialdigit\GUIDonedigit\GUIDonedigit\GUIDonedigit-%
\GUIDonedigit\GUIDonedigit\GUIDonedigit\GUIDonedigit
\GUIDonedigit\GUIDonedigit\GUIDonedigit\GUIDonedigit
\GUIDonedigit\GUIDonedigit\GUIDonedigit\GUIDonedigit
}
\makeatother
% this one is not expandable
\newcommand*{\GUIDnx}[1][.]{\begingroup\ifx.#1\else
\pdfsetrandomseed #1\relax\fi \GUID\endgroup}
% this one is not expandable
\newcommand*{\GUIDset}[2][.]{\begingroup\ifx.#1\else
\pdfsetrandomseed #1\relax\fi \xdef#2{\GUID}\endgroup}
\begin{document}
\ttfamily
\GUID\par
\GUID\par
\GUID\par
\edef\foo{\GUID}\meaning\foo<-- end of macro\par
\edef\foo{\GUID}\meaning\foo<-- end of macro\par
\GUIDnx [0]\par
\GUIDset[0]\foo
\meaning\foo<-- end of macro\par
\GUIDnx [123456789]\par
\GUIDset[123456789]\foo
\meaning\foo<-- end of macro\par
\end{document}
