Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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
从JavaScript中已知的一组潜在ID快速创建唯一字符串ID/键的方法_Javascript_Algorithm_Data Structures_Trie_Id Generation - Fatal编程技术网

从JavaScript中已知的一组潜在ID快速创建唯一字符串ID/键的方法

从JavaScript中已知的一组潜在ID快速创建唯一字符串ID/键的方法,javascript,algorithm,data-structures,trie,id-generation,Javascript,Algorithm,Data Structures,Trie,Id Generation,假设您想要一组1到2位的十六进制数,即256个数字。只是使用一个小集合来解决这个问题,但它可以处理任何大小的字符串 因此,在这种情况下,您有一个潜在的N或256个数字。您将为每个新的数据记录“生成”一个新的ID。因此,它开始并随机给你af,然后1d,然后8a,等等 简单而天真的方法是,只需按顺序生成所有数字,然后洗牌,然后从集合中弹出。当您只有256个数字时,这可以正常工作。但如果你有数百万或数十亿的数字,这是不切实际的,因为你可能有很多腰围生成的ID长时间不被使用。我想避免这种情况 所以我的问

假设您想要一组1到2位的十六进制数,即256个数字。只是使用一个小集合来解决这个问题,但它可以处理任何大小的字符串

因此,在这种情况下,您有一个潜在的
N
或256个数字。您将为每个新的数据记录“生成”一个新的ID。因此,它开始并随机给你
af
,然后
1d
,然后
8a
,等等

简单而天真的方法是,只需按顺序生成所有数字,然后洗牌,然后从集合中弹出。当您只有256个数字时,这可以正常工作。但如果你有数百万或数十亿的数字,这是不切实际的,因为你可能有很多腰围生成的ID长时间不被使用。我想避免这种情况

所以我的问题是,创建这样一个唯一的键字符串的最快方法是什么,不需要预先生成所有的键字符串,也不需要按顺序递增1或诸如此类的值。也就是说,密钥应该看起来是随机的

我可以想象的一种方法是使用trie存储已经使用/生成的值。然后,当您要获取一个新值时,您会生成一个随机值,然后检查trie以查看它是否已被使用。虽然我不知道如何判断这有多有效,但一旦你开始用完ID,并且只剩下最后几个ID,它的性能就会非常差。您将生成大量已经生成的ID,并遍历每个ID的trie,因此速度会很慢

我想知道是否有一种更有效的方法可以做到这一点,而不必事先生成所有这些内容。此外,数据记录不会用于计算ID,因为这些记录可能非常大和复杂

也许有一种方法可以对一次随机遍历(并生成)一个trie进行排序,这样就可以生成ID,因为您最终会在trie中的一个唯一的随机位置。我不知道,也许是这样的


另外,我对散列不太精通,所以我不知道是否有好的方法可以使用它。

我认为混合函数正是您想要的。它将在输入中移动位以产生相同长度的输出。它是可逆的,因此每个输入对应一个唯一的输出

由于您希望输入数据不参与id生成,因此需要一个代理id。您可以为每个记录分配一个递增id,并使用mix函数对id进行置乱

您将得到如下结果:

  • 记录A=>
    id==1
    =>
    混合id==0x7ed55d16
  • 记录B=>
    id==2
    =>
    混合id==0xc761c23c
  • 等等
请参见此处获得一些灵感:


    • 我认为在速度、灵活性和效率之间应该有一些折衷

      一方面,伪随机生成器将为您提供均匀的密钥分布,并且生成速度相当快。但是,检查现有id会很慢。您可以使用bloom过滤器(节省内存)或尝试,但正如您在某个时候所说的,您应该增加空间


      另一种选择是使用它来生成每个键(但不是随机顺序)。您需要跟踪上一次发布的代码。

      我不确定它的性能如何,但我的想法是使用
      对象
      映射
      Math.random()

      让obj={}
      函数生成器域(){
      设id=Math.abs(0.5-Math.random())*1000
      if(obj[id]){
      generateRandomId()
      }否则{
      obj[id]=真
      }
      返回id
      }
      console.log(generateRandomId())
      console.log(generateRandomId())
      console.log(generateRandomId())
      
      console.log(generateRandomId())
      我正在考虑这样的问题:

      var-trie=buildTrie()
      变量id1=genId(trie)
      变量id2=genId(trie)
      console.log(id1、id2)
      函数buildTrie(){
      var trie=buildNode(0)
      返回trie
      功能构建节点(级别){
      如果(电平==7){//8位
      变量节点={
      可用:正确,
      叶:是的
      }
      返回节点
      }否则{
      var a=构建节点(级别+1)
      var b=构建节点(级别+1)
      变量节点={
      是的,
      正确:正确,
      左:a,,
      右:b
      }
      a、 父节点=节点
      b、 父节点=节点
      返回节点
      }
      }
      }
      函数genId(节点){
      变量字节=[]
      步骤(节点,字节)
      var id=parseInt(bytes.join(“”),2.toString(16)
      返回id
      功能步骤(节点,字节){
      if(node.leaf){
      node.available=false
      var c=节点
      var p=c父项
      while(p){
      如果(p.left==c){
      p、 availableLeft=false
      }else if(p.right==c){
      p、 availableRight=false
      }
      如果(!p.availableLeft&!p.availableRight){
      c=p
      p=p.parent
      }否则{
      p=假
      }
      }
      }
      var randomDirection=Math.random()>=0.5
      如果(随机方向){
      if(node.availableLeft){
      字节。推送(0)
      步骤(node.left,字节)
      }else if(node.availableRight){
      字节数。推送(1)
      步骤(node.right,字节)
      }
      }否则{
      if(node.availableRight){
      字节数。推送(1)
      步骤(node.right,字节)
      }else if(node.availableLeft){
      字节。推送(0)
      步骤(node.left,字节)
      }
      }
      }
      
      }
      我假设您可以生成顺序ID;也就是说,您有一种可靠的方法可以准确地知道到目前为止已经生成了多少ID。然后,使用任何合理快速的加密算法对该计数进行加密就足够了

      加密将以二进制数的形式进行,大多数算法的加密结果都是相同大小的,也是二进制的。如果需要,可以对结果进行base-64或十六进制编码