小编典典

如何设计顺序的类似哈希的函数

algorithm

我想开发类似于jsfiddle的东西,用户可以在其中输入一些数据,然后“保存”并获得一个唯一的随机外观URL来加载该数据。

我不想使保存顺序进行,因为我不想让任何人抓住我的所有条目,因为有些条目可以是私人的。但是在服务器上,我想按顺序保存它。

是否有一种函数或技术可以将数字转换为具有4个字符的哈希,直到(62 * 62 * 62 * 62 === 14776336)输入之前没有任何冲突?

例如,服务器上的第一个条目将在服务器上命名1,但iUew3以用户命名,下一个条目将2在服务器上,但命名ueGR为用户…

编辑:我不确定是否很明显,但是这种类似于哈希的函数需要是可逆的,因为当用户请求ueGR服务器时,需要知道服务器文件2


阅读 265

收藏
2020-07-28

共1个答案

小编典典

可以执行此操作,但是我建议使用64个字符,因为这样会使操作变得更加容易。4个6位字符= 24位。

结合使用以下各项:

  • 位重新排序
  • 与数字异或
  • 将其放入24位最大长度的LFSR中,并执行几个循环。

强烈建议使用LFSR,因为它可以很好地加扰。其余的是可选的。所有这些操作都是 可逆的, 并确保每个输出都是 唯一的

计算“改组后的”数字时,只需将其打包为二进制字符串并使用进行编码base64_encode

对于解码,只需执行这些操作的逆操作即可。

样本(2 ^ 24长的唯一序列):

function lfsr($x) {
    return ($x >> 1) ^ (($x&1) ? 0xe10000 : 0);
}
function to_4($x) {
    for($i=0;$i<24;$i++)
        $x = lfsr($x);
    $str = pack("CCC", $x >> 16, ($x >> 8) & 0xff, $x & 0xff);
    return base64_encode($str);
}

function rev_lfsr($x) {
    $bit = $x & 0x800000;
    $x = $x ^ ($bit ? 0xe10000 : 0);
    return ($x << 1) + ($bit ? 1 : 0);
}
function from_4($str) {
    $str = base64_decode($str);
    $x = unpack("C*", $str);
    $x = $x[1]*65536 + $x[2] * 256 + $x[3];
    for($i=0;$i<24;$i++)
        $x = rev_lfsr($x);
    return $x;
}

for($i=0; $i<256; $i++) {
    $enc = to_4($i);
    echo $enc . " " . from_4($enc) . "\n";
}

输出:

AAAA 0
kgQB 1
5ggD 2
dAwC 3
DhAH 4
nBQG 5
6BgE 6
ehwF 7
HCAO 8
jiQP 9
+igN 10
aCwM 11
EjAJ 12
gDQI 13
9DgK 14
ZjwL 15
OEAc 16
qkQd 17
3kgf 18
TEwe 19
NlAb 20
pFQa 21
0FgY 22

...

注意:对于URL +,请/使用-和替换_

注意:尽管这可行,但对于像您这样的简单方案,创建随机文件名可能会更容易,直到它不存在为止。没有人关心条目的编号。

2020-07-28