4

I want to create unique ID numbers for my documents, and am doing so using a random number generator like this:

\usepackage[first=1, last=100000000]{lcg}
\newcommand{\random}{\rand\arabic{rand}}

However, really I would like to create a random number once on first build of the document and then have the same number used from then on in subsequent builds. Can I do this? and if so, how?

5
  • Hi, this is an interesting question and it looks like you've received a good answer. However, wouldn't it be easier to just create the random number some other way and hard-code it into your document? For example, you could use the following website. random.org/integers
    – James
    Oct 26, 2021 at 13:04
  • See the seed option for lcg (page 2 of manual). Oct 26, 2021 at 21:45
  • @JohnKormylo: Can you expand on how the seed option will help? The OP wants an initial random integer that is then retained for subsequent builds. I assume you are suggesting to use a seed value. But if the OP must enter a random seed, then they might as well just input a random document number instead, correct? Now if the OP needs many persistent random numbers generated in a single document, then I can see how a seed value would be useful.
    – James
    Oct 27, 2021 at 11:13
  • 1
    @James, yes, one could create the number some other way, but it imposes the burden to do this on all users of a document template I am creating. The solution provided hides this extra step from the users who then don't have to think about it. It's pretty cool.
    – crobar
    Oct 27, 2021 at 14:37
  • @crobar: I understand now. I didn't realize you were creating this for other users.
    – James
    Oct 27, 2021 at 15:19

3 Answers 3

5

You can save the generated random number to a file named \jobname.rid, then every time you build the document, it reads that file. If you delete the .rid file then a new random number is generated:

\begin{filecontents*}{myclass.cls}
\LoadClass{article}

% ID code
\ExplSyntaxOn
% Create a variable "\c_crobar_id_file_str" that contains the .rid file name:
\str_const:Nx \c_crobar_id_file_str { \c_sys_jobname_str . rid }
% Create a macro "\crobar@set@ID" that assigns its argument to the integer "\c_crobar_random_int":
\cs_new_protected:Npn \crobar@set@ID #1
  { \int_const:Nn \c_crobar_random_int {#1} }
% Check if the .rid file exists:
\file_if_exist:nTF { \c_crobar_id_file_str }
  {
    % If it does, input it:
    \file_input:n { \c_crobar_id_file_str }
  }
  {
    % If the file doesn't exist, create one and assign using \crobar@set@ID
    \crobar@set@ID { \int_rand:nn { 1 } { 100000000 } }
    % Then open the .rid file for writing (iow = IO/Write)
    \iow_open:Nn \g_tmpa_iow { \c_crobar_id_file_str }
    % Now write "\crobar@set@ID{<random number>}" to the .rid file
    \iow_now:Nx \g_tmpa_iow
      { \crobar@set@ID { \int_use:N \c_crobar_random_int } }
    % And close the .rid file
    \iow_close:N \g_tmpa_iow
  }
% Finally, create a user-level command \random that writes the integer \c_crobar_random_int
\cs_new:Npn \random { \int_to_arabic:n { \c_crobar_random_int } }
\ExplSyntaxOff
% ID code
\end{filecontents*}


\documentclass{myclass}
\begin{document}
This document ID is \random.
\end{document}

Running the document on my machine resulted in:

enter image description here

8
  • This could be the solution, thanks! However, is it possible to use an alternative file name/extension so that one can still delete the default aux file if necessary (or delete the ID file only)? Also, can this be used in a cls file to hide the complexity from users?
    – crobar
    Oct 26, 2021 at 12:30
  • @crobar Changed it to use a dedicated file. The code is the same whether it's in a class file, or in the preamble, as long as \random is not used before the random number is assigned. Oct 26, 2021 at 12:46
  • very impressive, thanks. Unfortunately I'll have to google every command to fully understand it!
    – crobar
    Oct 26, 2021 at 12:54
  • @crobar I added some comments along the code to (hopefully) make it easier to understand. The code uses mostly expl3 interface functions, so if you want to take a deeper look into how it works, I suggest looking for these functions in interface3.pdf instead. If there's any specific part you are having trouble to understand, feel free to ask Oct 26, 2021 at 13:08
  • I've been struggling a bit to use this. I tried putting the example all in one file and building it, but it failed. I then tried splitting into a cls and tex file with everything up to \end{filecontents*} in the cls. The first error I get is like ! Undefined control sequence. l.1 \crobar. I'm also curious about why there is no \begin{filecontents*}? Also I understand this is using LaTeX3 code, and after having searched, I'm not really sure what I need to do to use it in LaTeX2E?
    – crobar
    Oct 27, 2021 at 13:47
2

Not an answer, but extending the idea of an ID into the visual space:

Since a glyph in a font is (mapable to) a code-number, setting the randomizer to a Unicode codeblock, say, \int_rand:nn { 19968 } { 40938 }, running it multiple times and typesetting it in an appropriate font, a many-digit ID number can become an ID "phrase":

ID word

There are many blocks:

ID word2

Possible use-case could be to replace GUIDs or larger, representing them in a more compact form.

2

Try to load \jobname.rid, and if it fails, create a random ID to a command \docID and store its definition in \jobname.rid.

\documentclass{report}

\usepackage[first=1, last=100000000]{lcg}

\IfFileExists{\jobname.rid}
  {\input{\jobname.rid}}
  {\rand
   \def\docID{\arabic{rand}}
   % writing \def\docID{<ID>} to \jobname.rid
   \newwrite\docIDoutput
   \immediate\openout\docIDoutput=\jobname.rid
   \write\docIDoutput{\protect\def\protect\docID{\docID}}}

\begin{document}

ID: \docID

\end{document}

Caution: random seed seams to depend on time up to minute (so it is the same in runs within the same minute).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.