簡體   English   中英

如何設計順序類似哈希的函數

[英]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位。

使用以下組合:

  • 位重新排序
  • xor與數字
  • 將其置於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替換+/ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM