[Tex/LaTex] How to create a random string of random length

random

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?

Best Answer

Using Manuel's idea:

\documentclass{article}

\newcommand{\randomstring}{%
  \expandafter\generatestring\expandafter{\pdfuniformdeviate 26}%
}
\makeatletter
\newcommand{\generatestring}[1]{%
  \expandafter\@alph\expandafter{\number\numexpr1+\pdfuniformdeviate 26}%
  \ifnum#1>\z@
    \expandafter\@firstofone
  \else
    \expandafter\@gobble
  \fi
  {\expandafter\generatestring\expandafter{\number\numexpr#1-1}}%
}
\makeatother

\begin{document}

\randomstring

\randomstring

\randomstring

\edef\foo{\randomstring}\foo

\end{document}

This is fully expandable, as shown by the last call.

enter image description here

With \randomstring we first generate a number between 0 (included) and 26 (excluded), then we call recursively \generatestring with argument decreasing by 1 each time, until 0 is reached.

This works with pdfLaTeX or LuaLaTeX. No expandable way for XeLaTeX.


A version that works with all engines, but is not fully expandable.

\documentclass{article}

\input{random}
\newcount\randomlen
\newcount\randomletter

\makeatletter
\newcommand{\randomstring}{%
  \setrannum{\randomlen}{1}{26}%
  \loop\ifnum\randomlen>\z@
  \setrannum{\randomletter}{1}{26}%
  \@alph{\randomletter}%
  \advance\randomlen\m@ne
  \repeat
}
\makeatother

\begin{document}

\randomstring

\randomstring

\randomstring

\end{document}

enter image description here


A packaged solution. Save the following code as randomstring.sty

\ProvidesPackage{randomstring}[2014/11/06 v. 0.2]

\RequirePackage{ifxetex}

\newcommand{\setrandomstringlength}[1]{%
  \chardef\rstr@length=#1\relax
}
\setrandomstringlength{26}% default

\ifxetex

  \input{random}
  \newcount\randomlen
  \newcount\randomletter

  \newcommand{\rstr@randomstring}[1]{%
    \setrannum{\randomlen}{1}{\rstr@length}%
    \loop\ifnum\randomlen>\z@
      \setrannum{\randomletter}{1}{26}%
      #1%
      \advance\randomlen\m@ne
    \repeat
  }

  \newcommand{\randomstring}{%
    \rstr@randomstring{\@alph{\randomletter}}%
  }
  \newcommand{\defrandomstring}[1]{%
    \@ifdefinable#1{\def#1{}\rstr@randomstring{\rstr@add{#1}}}%
  }
  \newcommand{\rstr@add}[1]{%
    \edef#1{#1\@alph{\randomletter}}%
  }

\else

  \newcommand{\randomstring}{%
    \expandafter\rstr@generate\expandafter{\pdfuniformdeviate \rstr@length}%
  }
  \newcommand{\rstr@generate}[1]{%
    \expandafter\@alph\expandafter{\number\numexpr1+\pdfuniformdeviate 26}%
    \ifnum#1>\z@
      \expandafter\@firstofone
    \else
      \expandafter\@gobble
    \fi
    {\expandafter\rstr@generate\expandafter{\number\numexpr#1-1}}%
  }
  \newcommand{\defrandomstring}[1]{%
    \@ifdefinable#1{\edef#1{\randomstring}}%
  }

\fi

\endinput

Then run with any engine the following file

\documentclass{article}

\usepackage{randomstring}

\begin{document}

\randomstring

\randomstring

\randomstring

\defrandomstring{\foo}\texttt{\meaning\foo}

\setrandomstringlength{1}

\randomstring

\randomstring

\randomstring

\end{document}

Here's one instance of the result. Notice that after \setrandomstringlength{1} the strings have length 1.

The macro \defrandomstring stores the string in the macro passed as argument; if the macro is already defined, an error is raised.

enter image description here

Related Question