8

I'm looking for a way to create a string of random letters and random length. So whenever the command is used I get different strings.

\documentclass[11pt]{article}
\newcommand{\randomstring}{...}

\begin{document}
\randomstring
\randomstring

\end{document}

The out put could be

xkakhiw

or

khaggfpze

I think you got the idea. Could someone give me a hint, where to start?

schmendrich
  • 3,908
  • 2
    Any limit to the length of the strings? – egreg Nov 05 '14 at 14:56
  • 1
    A random number between 1 and a maximum determines the length (the maximum is necessary). A random number between 1 and 26 determines a letter (with \ifcase). This process repeated n times gives you the desired string (where n is the length, determined in the first step). I'm not sure, but I think to generate a random number (with pdfTeX at least) there is \pdfuniformdeviate but I don't know its syntax. – Manuel Nov 05 '14 at 15:04
  • @egreg: any number between 1 and 26. – schmendrich Nov 05 '14 at 15:08

1 Answers1

12

Using Manuel's idea:

\documentclass{article}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\randomstring}{} { \randomstring_make: }

\NewDocumentCommand{\defrandomstring}{sm} { \IfBooleanTF{#1}{\cs_set:Npe}{\cs_new:Npe} #2 { \randomstring_make: } }

\NewDocumentCommand{\setrandomstringlength}{m} { \int_set:Nn \l_randomstring_length_int { #1 } }

\int_new:N \l_randomstring_length_int

\cs_new:Nn \randomstring_make: { \prg_replicate:nn { \int_rand:n { \l_randomstring_length_int } } { \int_to_alph:n { \int_rand:n { 26 } } } }

\ExplSyntaxOff

\setrandomstringlength{26}

\begin{document}

\randomstring

\randomstring

\randomstring

\defrandomstring{\foo}

\texttt{\meaning\foo}

\setrandomstringlength{4}

\randomstring

\randomstring

\defrandomstring*{\foo}

\texttt{\meaning\foo}

\end{document}

With \setrandomstringlenght we set the upper bound to the length of the strings. A random integer between 1 and this upper bound (inclusive) is chosen and as many letters are randomly generated using \int_to_alph:n { \int_rand:n { 26 } }.

With \defrandomstring we can store a random string in a macro. The variant \defrandomstring* doesn't check whether the macro is already defined (use with care).

This works with any engine.

enter image description here

See edit history for a previous version.

egreg
  • 1,121,712
  • Pretty easy syntax for that primitive. I didn't know. – Manuel Nov 05 '14 at 15:24
  • @Manuel Yes, very handy. – egreg Nov 05 '14 at 15:49
  • @egreg: This is great. So I have to switch to lualatex? – schmendrich Nov 06 '14 at 18:27
  • @schmendrich If you're using XeLaTeX, it's possible to do the same, but not in an expandable way. Do you need it? – egreg Nov 06 '14 at 18:28
  • @egreg: I have to admit I have no clue what "expandable way" means :( Could you also provide a solution for xelatex? Why must xelatex have a different solution from the lualatex solution? – schmendrich Nov 06 '14 at 18:30
  • @schmendrich With "expandable” I mean something that can be generated and stored in a control sequence like I did for \foo; if you just need to print a random sequence (or also store it in a control sequence, but using an indirect way) I'll show how in a short time. – egreg Nov 06 '14 at 18:34
  • @egreg: wow, this is great. I like your package solution. Will walk through the code and try to understand it. It's a pleasure to learn from people like you. – schmendrich Nov 06 '14 at 19:22
  • @egreg I found this in early 2024. The packaged solution works in lualatex, but it is necessary to change \pdfuniformdeviate to \uniformdeviate due to changes made a few years ago. – rallg Jan 19 '24 at 21:16
  • 1
    @rallg Oh, nowadays we can do it in an engine independent way. Revamped. – egreg Jan 19 '24 at 21:45
  • @egreg Nice edit. Amazing. – rallg Jan 19 '24 at 22:23