Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 是否有一个函数接受两个值,让f(x,y)=f(y,x),并且输出是唯一的?_Algorithm_Language Agnostic_Encryption_Hash - Fatal编程技术网

Algorithm 是否有一个函数接受两个值,让f(x,y)=f(y,x),并且输出是唯一的?

Algorithm 是否有一个函数接受两个值,让f(x,y)=f(y,x),并且输出是唯一的?,algorithm,language-agnostic,encryption,hash,Algorithm,Language Agnostic,Encryption,Hash,我想知道是否有一种方法可以基于两个实体之间的关系生成一个键,使关系a->b的键与关系b->a的键相同 理想情况下,这将是一个哈希函数,它接受任何一个关系成员,但不管成员的显示顺序如何,都会生成相同的输出 显然,你可以用数字来做这件事(例如,加法(2,3)相当于加法(3,2))。我的问题是,我不想让加法(1,4)等于加法(2,3)。显然,任何哈希函数都有重叠,但我的意思是唯一性的感觉很弱 我天真的(也是不受欢迎的)想法是: function orderIndifferentHash(string

我想知道是否有一种方法可以基于两个实体之间的关系生成一个键,使关系a->b的键与关系b->a的键相同

理想情况下,这将是一个哈希函数,它接受任何一个关系成员,但不管成员的显示顺序如何,都会生成相同的输出

显然,你可以用数字来做这件事(例如,加法(2,3)相当于加法(3,2))。我的问题是,我不想让加法(1,4)等于加法(2,3)。显然,任何哈希函数都有重叠,但我的意思是唯一性的感觉很弱

我天真的(也是不受欢迎的)想法是:

function orderIndifferentHash(string val1, string val2)
{
  return stringMerge(hash(val1), hash(val2));
  /* String merge will 'add' each character (with wrapping).
     The pre-hash is to lengthen strings to at least 32 characters */
}

在函数
orderInferenceThash
中,您可以首先按照某些条件对
val1
val2
进行排序,然后应用任何希望得到结果的哈希函数

function orderIndifferentHash( val1, val2 ) {
  if( val1 < val2 ) {
    first = val1
    second = val2
  }
  else {
    first = val2
    second = val1
  }
  hashInput = concat( first, second )
  return someHash( hashInput )

  // or as an alternative:
  // return concat( someHash( first ), someHash( second ) )
}
函数顺序无差异(val1,val2){
if(val1
您的目标是:

一些函数
f(x,y)
使得

  • f(x,y)==f(y,x)
  • f(x,y)!=f(a,b)=>(x==a
    y==b
    )或(
    x==b
    y==a
将会有很多这样的东西,我能想到的就是“排序连接”:

  • 按任意顺序排序
    (x,y)
  • 将散列函数
    u(a)
    分别应用于
    x
    y
    (其中
    u(a)=u(b)
    意味着
    a==b
    ,并且
    u(a)
    的长度是恒定的)
  • 连接
    u(x)
    u(y)
  • 在这种情况下:

    如果
    x==y
    ,那么这两个哈希值基本相同,因此不会失去一般性
    x
    ,因此:

    • f(y,x)=u(x)+u(y)=f(x,y)
    此外,如果
    f(x,y)==f(a,b)
    ,这意味着:

    • u(x)==u(a)
      u(y)==u(b)
      =>
      x==a
      y==b
      ,或
    • u(y)==u(a)
      u(x)==u(b)
      =>
      y==a
      x==b
    短版:


    对x和y进行排序,然后在结果哈希长度不变的情况下应用任何哈希函数。

    对于数字,一种实现方法是对两个数字
    x
    y
    取第x个素数和第y个素数,并计算这些素数的乘积。这样,您将保证每个不同的
    x
    y
    对的乘积的唯一性,并且独立于参数顺序。当然,为了以实际有意义的效率做到这一点,您需要为
    x
    y
    的所有可能值保留一个素数表。如果从相对较小的范围中选择
    x
    y
    ,这将起作用。但是如果范围很大,表本身就变得不切实际,您将别无选择,只能接受一些冲突概率(比如保留一个大小合理的N素数表,并为给定的
    x
    选择x%N次素数)

    其他答案中已经提到的另一种解决方案是构建一个完美的哈希函数,该函数对
    x
    y
    值起作用,然后简单地将
    x
    y
    的哈希连接起来。订单独立性是通过预排序
    x
    y
    实现的。当然,构建一个完美的散列只能用于一组范围相当小的参数


    有些事情告诉我,基于素数的方法将为您提供满足所需条件的尽可能短的哈希。不,不是真的。

    假设您有任何散列
    h(x,y)
    。然后定义
    f(x,y)=h(x,y)+h(y,x)
    。现在有了一个对称散列


    (如果你做一个简单的乘法“散列”,那么1+3和2+2可能会散列到相同的值,但即使是像h(x,y)=x*y*y这样的东西也可以避免——只要确保散列函数的至少一个参数中存在一些非线性。)

    是的,但只有当
    u
    是一个完美的散列函数,即
    u(a)==u(b)时,这才是真的
    相当于
    a==b
    。Duh…排序。。。我现在觉得自己很愚蠢——只要这两个值是可排序的,我们就可以按照相同的顺序进行散列。你能解释一下你所说的
    =>
    是什么意思吗?我假设“除非”(假设你说的是
    f(x,y)!=f(a,b)=>(x==a和y==b…)
    但我习惯于把它看作“因此”(正如你在底部使用的那样)。关于接受哪一个很难,另一个是第一个,完美地回答了这个问题,但这个答案更明确,背后有各种假设/想法(一旦你计算出排序,这一切都是显而易见的)。@Kragen:我不会将这两个散列连在一起(如果结果是数字的话,这甚至是不可能的),我宁愿将它们组合起来。有关组合的示例,请参见
    boost::hash_combine
    :如果在哈希后进行连接,则会引入一些潜在的漏洞(取决于您对结果的处理)。例如,如果我看到两个输出
    f(x1,y1)
    f(x2,y2)
    有一个共同的前缀或后缀,那么我知道其中一个输入是共同的。好主意。不幸的是,性能会扼杀我的用例,但我喜欢这种总是让我感到惊讶的想法。如果你使用的数字“足够小”(比如,32位体系结构上的16位整数或64位体系结构上的32位整数),您只需将最低(最高)n位移到th