为了在许多不同的表格环境中识别对象,我想创建一个包含 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