我正在尝试通过PHP解决以下问题。目的是基于整数种子生成唯一的6个字符的字符串,并包含预定义的字符范围。第二个要求是字符串必须是随机的(所以如果代码1是100000,则代码2不能接受100001和3 100002)
字符范围是:
如果我没有弄错的话,这将是总共26个字符。我的第一个想法是从编号7962624开始从基数10到基数24进行编码。所以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个代码转储到数据库中并随机检索它们我完全没有想法。
斯蒂芬
答案 0 :(得分:7)
如果你输入你的输入序列1,2,3 ...并且应用一个模数为素数的线性映射,你会得到一个相当随机的序列。唯一代码的数量仅限于素数,因此您应选择较大的代码。只要您选择一个不能被素数整除的乘数,结果代码就是唯一的。
以下是一个示例:使用6个字符可以生成26个 6 = 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。