如何创建固定长度的字母数字哈希字符串?

如何创建固定长度的字母数字哈希字符串?

为了在许多不同的表格环境中识别对象,我想创建一个包含 5 位数字(仅大写字母)的伪随机哈希字符串。在这种情况下,连续增加的数字是不可能的。

我正在寻找一个宏,每次调用它时都会给我一个不同的哈希字符串。但该值必须与编译周期无关。

结果应类似于此 MWE:

\documentclass{article}%
\usepackage[a4paper,left=10mm,right=10mm,top=10mm,bottom=10mm]{geometry}%

\begin{document}
\begin{tabular}{|c|c|}
\hline
\textbf{HASH} & \textbf{Description} \\ \hline
A4X75 & This is the first Hash \\ \hline
7T0LE & This is the second Hash \\
\hline
\end{tabular}
\end{document}

表格

答案1

如果你不在其他地方使用伪随机数,

\documentclass{article}

\ExplSyntaxOn

\sys_gset_rand_seed:n { 0 }% or whatever

\NewExpandableDocumentCommand{\hash}{}
 {
  \int_to_Base:nn { \int_rand:nn { 36 } { 1295 } } { 36 } % two digits
  \__pascals_hash_three:e { \int_to_Base:nn { \int_rand:n { 46655 } } { 36 } } % three digits
 }
\cs_new:Nn \__pascals_hash_three:n
 {
  \prg_replicate:nn { 3 - \tl_count:n { #1 } } { 0 } #1
 }
\cs_generate_variant:Nn \__pascals_hash_three:n { e }

\ExplSyntaxOff

\begin{document}

\begin{tabular}{|c|c|}
\hline
\textbf{HASH} & \textbf{Description} \\ \hline
\hash & This is the first Hash \\ \hline
\hash & This is the second Hash \\
\hline
\end{tabular}

\end{document}

固定种子将允许每次运行时精确复制。

在此处输入图片描述

您计算获得重复项的概率。

如果由于哈希值与数字数量相比过多而需要避免重复,则会失去可扩展性。

\documentclass{article}

\ExplSyntaxOn

\sys_gset_rand_seed:n { 0 }% or whatever

\NewDocumentCommand{\hash}{}
 {
  \pascals_hash:
 }

\tl_new:N \l__pascals_hash_try_tl
\seq_new:N \g_pascals_hash_used_seq

\cs_new_protected:Nn \pascals_hash:
 {
  % generate a tentative hash
  \tl_set:Ne \l__pascals_hash_try_tl
   {
    \int_to_Base:nn { \int_rand:nn { 36 } { 1295 } } { 36 } % two digits
    \__pascals_hash_three:e { \int_to_Base:nn { \int_rand:n { 46655 } } { 36 } } % three digits 
   }
  % check for duplicate
  \seq_if_in:NVTF \g_pascals_hash_used_seq \l__pascals_hash_try_tl
   {% it's a duplicate, retry
    \pascals_hash:
   }
   {% not a duplicate
    \seq_gput_right:NV \g_pascals_hash_used_seq \l__pascals_hash_try_tl
    \tl_use:N \l__pascals_hash_try_tl
   }
 }

\cs_new:Nn \__pascals_hash_three:n
 {
  \prg_replicate:nn { 3 - \tl_count:n { #1 } } { 0 } #1
 }
\cs_generate_variant:Nn \__pascals_hash_three:n { e }

\ExplSyntaxOff

\begin{document}

\begin{tabular}{|c|c|}
\hline
\textbf{HASH} & \textbf{Description} \\ \hline
\hash & This is the first Hash \\ \hline
\hash & This is the second Hash \\
\hline
\end{tabular}

\end{document}

答案2

我展示了如何使用 OpTeX。我们没有准备好的宏,例如\_int_to_Base,所以我们必须使用 LauTeX 原语\Uchar\uniformdeviate我们在循环中生成六位数字。字符串中出现数字的概率设置为 1/3。

\setrandomseed 100 % radom generator initialized, the same for all compilation
\def\randomchar#1#2{\Uchar\numexpr`#1+\uniformdeviate\numexpr`#2-`#1\relax\relax}
\def\randomhash{%
    \fornum 1..6 \do
        {\ifnum\uniformdeviate3 >1 \randomchar 09\else \randomchar AZ\fi}%
}
\def\createhash{\edef\hash{\randomhash}%
   \ifcsname hash:\hash \endcsname \ea\createrandomhash % the hash is already used
   \else \sxdef{hash:\hash}{}\hash \fi
} 

\table{|(\tt)c|c|}{\crl
   \bf HASH    & \bf Description \crl
   \createhash & This is the first Hash \crl
   \createhash & This is the second Hash \crl
}

\bye

相关内容