简体   繁体   中英

How can I generate unique key using two different numbers and then retrieve this key by using one of these numbers

Having two different numbers I have to generate a unique key. For example I have 37 and 8, and by using XOR on them I will get 45, that's my unique key. But then I need to retrieve this unique key by using one of those numbers (37 or 8). So question is, how can I generate unique key using two different numbers and then retrieve this key by using one of these numbers? It's allowed to use some third number (mask, key, etc.), but I need a unique key to be really unique.


Edit:

All right guys, sorry for probably non clear question. I have in-memory key-object storage. Memcached for example, no matters. There I can add some value and specify string key for an object eg Cache.Add(“mykey”, myobj); But in my app same object have two identifiers, integer and string. So I want to be able add into cache like this Cache.Add(“mykey”, 1, myobj); And then to get same cached object by using one of the identifiers. Like this Cache.Get(1) or Cache.Get(“mykey”); String can be computed into hash, so that's why I asked about two integers. My storage is SharedCache ectualy. I just don't want to change core of SharedCahce, so probably there is a solution for computing key by one of the identifiers.


Ok, guys. Thanks for your answers. But what if use some third static number for computing key/hash. And then use it with one of the identifiers (numbers) for determining the key, N1 = 37 N2 = 8 SN3 = 999 (hardcoded) key(n1, n2) = key(n1,sn3) = key(n2,sn3)

Also I'm thinking about keeping my identifiers in QWORD. Hash from string identifier is kept in higher DWORD and int identifier is kept in lowest DWORD. Then in methods Cache.Get I can determine type of parameter, if its int so lookup in lower DWORD and if type is string, lookup in higher DWORD.

Below is another approachm without XOR:

To generate a unique key x from 2 integers (a,b) and be able to find (a,b) from this key you can proceed as below:

generate x from a and b:

x = (2**a).(3**b) //(** means power)

there is a unique decompostion of x since 2 and 3 are prime numbers

Then to get a and b from x;

 divide x by 2 until you don't get an integer => number of division =a
 divide x by 3 until you don't get an integer => number of division =b

Example of code (in python sorry I don't know C# well):

>>> def keyGenerator(a,b):
    return (2**a)*(3**b)

>>> def findNumbersFromKey(x):
    a=0
    b=0
    while(x%2 ==0):
        a+=1
        x/=2
    while(x%3 == 0):
        b+=1
        x/=3
    return a,b

>>> keyGenerator(5,4)
2592
>>> findNumbersFromKey(2592)
(5, 4)
>>> keyGenerator(25,14)
160489808068608L
>>> findNumbersFromKey(160489808068608L)
(25, 14)

key(a,b):= a XOR b is not unique at all as for example key(8,7) = 15 = key(12,3).

Assuming that your pairs (a,b) are values in the ranges 0 <= a < N and 0 <= b < M you could assign key(a,b):= a + b * N which is unique and in the range 0 <= key(a,b) < M*N.

I don't understand what you mean with "But then I need to retrieve this unique key by using one of those numbers (37 or 8)." . Do you want to be able to compute key(37,8) given only 37 as input? This would be impossible. How do you want to distinguish between key(37,8) and key(37,1234) given only 37 as input?


Update:

As noted before, if both keys are independent (ie neither of them can be computed efficiently from the other one) you cannot do this "compute the unique key from only one identifier" stuff.

To solve your problem I would suggest the following, based on the information you gave and assuming that both identifiers are known when Add() is called and that either identifier on its own is sufficient to uniquely identify each object:

Add a "Hashtable aliasTable" member to "Cache". When "Cache.Add(strID, intID, obj)" is called, use "intID" as the unique key. Additionally, let "aliasTable[strID] = intID". On a "Cache.Get(intID)" just use "intID" as unique key. On "Cache.Get(strID)" retrieve the unique key via "intID = aliasTable[strID]".

If you do the cache lookup more often via strID than intID, then use that as unique key and use aliasTable the other way round (mapping intID to strID).

If you want to generate a unique key just concatenate the two unique numbers.

In my case I was needed to create a unique room_id for socket.io from the mobile numbers of two user.

In this way

key(n1,n2) != key(n1,sn3) != key(n2,sn3) 

How unique is unique? XORing two numbers is hardly a great method for generating unique numbers.

That said, for your specific example, given one input number and your key, then XORing those two together will give the second key.

a XOR b = c
c XOR b = a

Just intersperse the two numbers. Eg if you have a=1234 and b=99:

a =   1 2 3 4 
b =      9 9 
key = 1029394 

Note that the key is much smaller than in Ricky's proposal.

Store a reference to the object twice, once with each key. Then it can be retrieve with either key. If you need the ability to delete items from the cache, then you will want to delete both references. To facilitate that, you could store both keys in the object itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM