[英]How to design a sequential hash-like function
我想開發類似於jsfiddle的東西,用戶可以在其中輸入一些數據,然后“保存”它並獲得一個加載該數據的獨特隨機查找URL。
我不想讓保存順序,因為我不希望任何人抓住我的所有條目,因為有些可能是私有的。 但是在服務器上我想按順序保存它。
是否存在將數字轉換為具有4個字符而沒有任何沖突的散列的函數或技術,直到(62 * 62 * 62 * 62 === 14776336)
條目(62 * 62 * 62 * 62 === 14776336)
?
例如,服務器上的第一個條目將在服務器上命名為1
,而iUew3
將命名為用戶,下一個條目在服務器上為2
,但ueGR
為用戶...
編輯:我不確定它是否顯而易見但這個類似哈希的函數需要是可逆的,因為當用戶請求ueGR
服務器需要知道服務器它的文件2
可以這樣做,但我建議使用64個字符,因為這將使它更容易。 4個6位字符= 24位。
使用以下組合:
強烈建議使用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替換+
和/
with -
和_
。
注意:雖然這有效,但對於像您這樣的簡單場景,創建隨機文件名可能更容易,直到它不存在。 沒有人關心參賽作品的數量。
這是我實現它的方式。 這是save.php文件(有人可以告訴我它是否有任何設計缺陷):
<?php
$index = file_get_contents('saves/data/placeholder');
$index++;
file_put_contents('saves/data/placeholder', $index);
$string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
do {
$hash = $string[rand(0, 61)] . $string[rand(0, 61)] . $string[rand(0, 61)] . $string[rand(0, 61)];
} while (file_exists('saves/' . $hash));
file_put_contents('saves/' . $hash, $index);
file_put_contents('saves/data/' . $index, $_REQUEST['data']);
echo $hash;
?>
這里是load.php:
<?php
if (!file_exists('saves/' . $_REQUEST['file'])) {
file_put_contents('saves/data/log', 'requested saves/' . $_REQUEST['file'] . "\n", FILE_APPEND);
die();
}
$file_pointer = file_get_contents('saves/' . $_REQUEST['file']);
if (!file_exists('saves/data/' . $file_pointer)) {
file_put_contents('saves/data/log', 'requested saves/data/' . $file_pointer . 'from ' . $_REQUEST['file'] . "\n", FILE_APPEND);
die();
}
echo file_get_contents('saves/data/' . $file_pointer);
?>
希望這有助於其他人。
這是一個可逆的lib,與bcmath一起工作
http://blog.kevburnsjr.com/php-unique-hash
在我看來,如果你還保留在服務器上的save time of entry
,你可以生成一個哈希函數。 hash = func(id, time)
但只有hash = func(id)
才能輕松解決
這是一組奇怪的約束。 我經常使用MD5校驗和從數據生成唯一的URL。 如果用戶還沒有數據,則無法猜測URL。
我確實理解不想使用數據庫 - 如果你之前從未使用過數據庫,那么學習曲線可能會有點陡峭。
我不明白“在服務器上順序存儲事物”的限制。 如果您需要知道創建哈希的順序,我只需將該信息放在一個單獨的文件中。 您可能必須執行文件鎖定或其他類型的黑客操作,以確保您可以遞增地將哈希附加到該文件。
如果您想要短URL,您可以采用MD5校驗和的前綴,也可以采用CRC-32和base64編碼。 兩者都會為您提供具有相當好概率的唯一URL。
這實際上不可逆轉。 唯一的方法(url shorteners和jsfiddle使用的方法)是將生成的哈希(實際上它是摘要)存儲在某種表格/數據結構中,並在檢索時查找它。
為什么這個?
傳遞,例如128個數據字符→4個可見的字符摘要,會丟失大量數據 。
你不能將剩下的數據存儲在這4個字節之間的神奇裂縫中,沒有。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.