How to design a sequential hash-like function

后端 未结 6 433
谎友^
谎友^ 2020-12-14 04:57

I want to develop something similar to jsfiddle in where the user can input some data and then \"save\" it and get a unique random looking url that loads that data.

6条回答
  •  自闭症患者
    2020-12-14 05:34

    It's possible to do this, but I would suggest using 64 characters, as that will make it a lot easier. 4 6bit characters = 24bits.

    Use a combination of these:

    • bit reordering
    • xor with a number
    • put it into a 24bit maximal length LFSR and do a couple of cycles.

    LFSR is highly recommended as it will do a good scrambling. The rest are optional. All of these manipulations are reversible and guarantee that each output is going to be unique.

    When you calculated the "shuffled" number simply pack it to a binary string and encode it with base64_encode.

    For decoding simply do the inverse of these operations.

    Sample (2^24 long unique sequence):

    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";
    }
    

    Output:

    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
    
    ...
    

    Note: for URL replace + and / with - and _.

    Note: although this works, for a simple scenario like yours it's probably easier to create a random filename, till it doesn't exist. nobody cares about the number of the entry.

提交回复
热议问题