我正在尝试通过PHP解决以下问题。目的是基于整数种子生成唯一的 6 个字符的字符串,并包含预定义的字符范围。 第二个要求是字符串必须随机出现(因此,如果代码 1 为 100000,则代码 2 100001且 3 100002是不可接受的(
字符范围为:
- 大写 A-Z 不包括:B、I、O、S 和 Z
- 0-9 不包括: 0, 1, 2, 5, 8
因此,如果我没记错的话,总共会有 26 个字符。我的第一个想法是从第 10 基数编码到基数 24,从数字 7962624 开始。7962624 + 种子也是如此,然后 base24 对该数字进行编码。
这给了我字符 0-N。 如果我以下列方式替换生成的字符串,则满足第一个条件:
B=P, I=Q, 0=R, 1=T, 2=U, 5=V, 8=W
所以在这一点上,我的代码将看起来像这样:
1=TRRRR, 2=TRRRT, 3=TRRRU
所以我要问你们大师的问题是:我怎样才能制作一个行为一致(因此给定整数的返回字符串始终相同(并满足上述 2 个要求的方法?我现在花了整整 2 天的时间,除了将 700,000,000 个代码转储到数据库中并随机检索它们之外,我都不知道了。
斯蒂芬
如果你把你的输入序列1,2,3...应用线性映射模一个素数,你会得到一个相当随机的序列。唯一代码的数量仅限于质数,因此您应该选择一个大代码。只要您选择不可被素数整除的乘数,生成的代码将是唯一的。
这里有一个例子:用 6 个字符,你可以使 266=308915776 个唯一的字符串,所以可以308915753合适的质数。因此,此函数将生成超过 300.000.000 个唯一代码:
function encode($num) {
$scrambled = (240049382*$num + 37043083) % 308915753;
return base_convert($scrambled, 10, 26);
}
请确保在 64 位 PHP 上运行它,否则乘法将溢出。在 32 位上,您必须使用 bcmath
.为数字 1 到 9 生成的代码是:
n89a2d
hdh4jo
biopb9
5o6k2k
3eek5
k8m9aj
ee4424
8jbojf
2ojjb0
剩下的就是填写有时丢失的初始 0 并替换字母和数字,这样就不会产生任何禁止的字符。
如您所见,没有明显的模式,但是有时间,有足够的动力并可以访问其中的一些代码的人将能够找出正在发生的事情。更安全的替代方法是使用块大小较小的加密算法,例如 Skip32。