繁体   English   中英

如何使用两个不同的数字生成唯一密钥,然后使用这些数字之一检索此密钥

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

有两个不同的数字我必须生成一个唯一的密钥。 例如,我有 37 和 8,通过对它们使用 XOR,我将得到 45,这是我的唯一键。 但随后我需要使用其中一个数字(37 或 8)来检索这个唯一键。 所以问题是,如何使用两个不同的数字生成唯一密钥,然后使用这些数字之一检索该密钥? 允许使用第三个数字(掩码、密钥等),但我需要一个唯一的密钥才能真正唯一。


编辑:

好的,对于可能不清楚的问题,抱歉。 我有内存中的键对象存储。 以 Memcached 为例,没关系。 在那里我可以为 object 添加一些值并指定字符串键,例如 Cache.Add(“mykey”, myobj); 但在我的应用程序中,同样的 object 有两个标识符,integer 和字符串。 所以我希望能够像这样添加到缓存中 Cache.Add(“mykey”, 1, myobj); 然后使用其中一个标识符获取相同的缓存 object。 像这样 Cache.Get(1) 或 Cache.Get(“mykey”); 字符串可以计算成 hash,所以这就是我问两个整数的原因。 我的存储实际上是 SharedCache。 我只是不想改变 SharedCahce 的核心,所以可能有一个通过标识符之一计算密钥的解决方案。


好了朋友们。 感谢您的回答。 但是,如果使用第三个 static 数字来计算密钥/哈希怎么办。 然后将其与用于确定密钥的标识符(数字)之一一起使用,N1 = 37 N2 = 8 SN3 = 999(硬编码) key(n1, n2) = key(n1,sn3) = key(n2,sn3)

另外我正在考虑将我的标识符保存在 QWORD 中。 来自字符串标识符的 Hash 保存在较高的 DWORD 中,而 int 标识符保存在最低的 DWORD 中。 然后在方法 Cache.Get 我可以确定参数的类型,如果它的 int 则在较低的 DWORD 中查找,如果类型是字符串,则在较高的 DWORD 中查找。

下面是另一种没有异或的方法:

要从 2 个整数 (a,b) 生成唯一键 x 并能够从该键中找到 (a,b),您可以执行以下操作:

从 a 和 b 生成 x:

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

因为 2 和 3 是素数,所以 x 存在唯一的分解

然后从x中得到a和b;

 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

代码示例(在 python 对不起,我不太了解 C#):

>>> 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 根本不是唯一的,例如 key(8,7) = 15 = key(12,3)。

假设您的对 (a,b) 是 0 <= a < N 和 0 <= b < M 范围内的值,您可以分配 key(a,b):= a + b * N 这是唯一的并且在范围内0 <= 键(a,b)< M*N。

我不明白您所说的“但是我需要使用其中一个数字(37 或 8)来检索这个唯一键”是什么意思。 . 您是否希望仅给定 37 作为输入来计算 key(37,8)? 这是不可能的。 仅给定 37 作为输入,您想如何区分 key(37,8) 和 key(37,1234)?


更新:

如前所述,如果两个键都是独立的(即它们都不能从另一个有效地计算出来),那么您不能这样做“仅从一个标识符计算唯一键”的东西。

为了解决您的问题,我会根据您提供的信息提出以下建议,并假设在调用 Add() 时两个标识符都是已知的,并且任一标识符本身就足以唯一标识每个 object:

将“Hashtable aliasTable”成员添加到“Cache”。 调用“Cache.Add(strID, intID, obj)”时,使用“intID”作为唯一键。 此外,让“aliasTable[strID] = intID”。 在“Cache.Get(intID)”上,只需使用“intID”作为唯一键。 在“Cache.Get(strID)”上,通过“intID = aliasTable[strID]”检索唯一键。

如果您通过 strID 而不是 intID 更频繁地进行缓存查找,则将其用作唯一键并反过来使用 aliasTable(将 intID 映射到 strID)。

如果要生成唯一键,只需连接两个唯一数字。

在我的情况下,我需要根据两个用户的手机号码为socket.io创建一个唯一的room_id

这样

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

独特性有多独特? 异或两个数字并不是生成唯一数字的好方法。

也就是说,对于您的具体示例,给定一个输入数字和您的密钥,然后将这两者异或将给出第二个密钥。

a XOR b = c
c XOR b = a

只需穿插两个数字。 例如,如果您有 a=1234 和 b=99:

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

请注意,密钥比 Ricky 的提议要小得多。

存储对 object 的引用两次,每个密钥一次。 然后可以使用任一键检索它。 如果您需要从缓存中删除项目的能力,那么您将需要删除这两个引用。 为此,您可以将这两个密钥存储在 object 本身中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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