使用set Prefix创建GUID

时间:2008-12-09 13:18:01

标签: c# guid

我想知道是否有办法生成有效的GUID / UUID,其中第一个(或任何部分)部分是用户选择的前缀。

即,GUID的格式为AAAAAAAA-BBBB-CCCC-DDDD-DDDDDDDDDDD,我想将任何部分设置为预定义值(理想情况下为AAA)。目标是使GUID仍然是全局唯一的,但它们不需要加密安全。

6 个答案:

答案 0 :(得分:5)

嗯......所以,你基本上喜欢12字节的GUID?因为,一旦你删除前4个字节(你的AAA)的唯一性,你就broken the existing algorithm - 你需要提出自己的算法。

根据相关的RFC,GUID格式分解为:

  UUID                   = time-low "-" time-mid "-"
                           time-high-and-version "-"
                           clock-seq-and-reserved
                           clock-seq-low "-" node
  time-low               = 4hexOctet
  time-mid               = 2hexOctet
  time-high-and-version  = 2hexOctet
  clock-seq-and-reserved = hexOctet
  clock-seq-low          = hexOctet
  node                   = 6hexOctet
  hexOctet               = hexDigit hexDigit
  hexDigit =
        "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
        "a" / "b" / "c" / "d" / "e" / "f" /
        "A" / "B" / "C" / "D" / "E" / "F"

其中唯一的静态数据是版本(4位)和保留/变量(2-3位)。我没有看到他们允许任何“用户指定”版本,但是如果您使用1111作为您的版本标识符,我会说在可预见的将来您将是安全的。现有版本在4.1.3节中,但到目前为止只定义了5个版本......在碰撞之前会再给你11个版本。

所以,如果你可以使用6或7位的清晰度,Guid.NewGuid().ToByteArray()的组合以及在你的位摆弄之后创建一个new Guid可以让你到达那里。

答案 1 :(得分:4)

抱歉,你想要一个GUID太多了。从您的问题和您自己的答案/更新中总结出来,您希望它

  • 1是GUID
  • 2不与任何其他GUID(全局唯一)碰撞
  • 3使用保留值
  • 忽略对第一位解释的标准
  • 4对剩余位使用个人方案

这是不可能的,证明: 如果可能,我可以生成一个GUID G1,你可以生成另一个GUID G2。由于我们都忽略了标准并使用相同的保留前缀,并且我对其他位的个人方案不在您的控制之内,因此我的GUID G1可能与您的GUID G2冲突。 GUID的非冲突属性遵循GUID标准。

防止冲突的机制确实具有隐私敏感性。如果我随机生成GUID G1,我可以保证如果满足两个条件,则随机GUID是唯一的:

  • 1它是我控制下的GUID子集的成员,
  • 2之前我没有生成GUID。

对于您控制的子集之外的GUID,您无法保证(2)。但是,如何将GUID的非重叠子集分配给单个人?使用NIC的MAC是一种简单有效的方法。其他手段也是可能的。但无论如何,仅存在这样一个子集就是隐私隐含的。它必须属于某人,我必须能够确定这是我还是其他人。要证明两个随机GUID G1和G2是否属于同一个子集(即人)有点困难,但是当前的方案(你反对)不会试图隐藏它。

答案 2 :(得分:2)

无法创建GUID / UUID,其中第一个(或任何部分)部分是用户选择的前缀,而您可以编写自己的函数来创建具有相同数字(36/38)字符的唯一ID。

答案 3 :(得分:0)

你可以简单地创建一个Guid,并将前缀改为你想要的样子。 在操作系统项目中已经看到了这一点,通过生成如此多的guid来抛出并解决相同的问题,直到一个匹配希望的前缀(呃!)。

Guid g = Guid.NewGuid(); string gs = g.ToString(); Guid f = new Guid(string.Format("{0}-{1}", "AAAAAAAA", gs.Substring(gs.IndexOf('-') + 1)));

不好,但有效。

在这个主题的其他帖子中让我感到困扰的是,一个guid应该是全球唯一的,在所有情况下都是错误的,它有足够的空间来生成独特的guid,但没有任何保证全球唯一的。即使在制作指南时也不考虑时间。

答案 4 :(得分:0)

感谢。这些尝试的问题在于它们不能保证全局唯一,正如Raymond Chen指出的那样。我想知道是否有另一种算法生成唯一的GUID。我记得曾经有过使用时间戳和/或NIC MAC地址的实现,但它们不再使用,因为它们不具有加密性和/或存在隐私问题。

我想知道:如果我只是自己做,我应该没事?根据{{​​3}}:

  

数据4中第二个字节的一到三个最高有效位定义了GUID的类型变体:

     

模式描述
  0网络计算系统向后兼容性
  10标准
  110 Microsoft组件对象模型向后兼容;这包括用于IUnknown和IDispatch等重要接口的GUID   111保留供将来使用。

     

Data3的最重要的四位定义了版本号和使用的算法。

因此,如果我在Data3 / Data4中构建一些东西,我通常会创建自己的实现,不应该与任何其他GUID冲突,但当然总是存在一些与之相关的风险,所以在此之前我想要检查是否有更老的/不再使用的algorhithm产生真正的唯一ID。

答案 5 :(得分:0)

我最近有类似的需求 - 我需要一个GUID:

  • 由标准guid算法创建,因此有可能成为全球唯一
  • 有一个已定义的前缀。

正如您可能想象的那样,我正在做一些我不应该做的事情。

你在其中一条评论中提到你可以让GUID生成器运行,直到碰巧用你需要的前缀命中guid。这就是我采取的策略。这是代码:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string target_prefix = "dead";

            while (true)
            {
                Guid g = Guid.NewGuid();
                string gs = g.ToString();
                if (gs.Substring(0, target_prefix.Length) == target_prefix)
                {
                    Console.WriteLine("Match: " + gs);
                }
                else
                {
                    //Console.WriteLine("Mismatch: " + gs);
                }
            }
        }
    }
}

对于较小的前缀,它可以更快地生成匹配。我敢打赌它是目标前缀每个数字的16倍。