如何创建不包含数字的唯一标识符?

时间:2013-09-05 20:48:14

标签: c# guid uniqueidentifier uid

我希望在.resx文件中使用某种唯一标识符,但它不允许键以数字开头。在我得到以字母开头的GUID之前,我不想循环访问GUID,而是想知道是否存在替代UID类型,该类型不包含数字或者否则将满足此要求。

有什么想法吗?

7 个答案:

答案 0 :(得分:9)

如果你只是想用一个字母创建一个启动的Guid,你可以这样做:

var b = Guid.NewGuid().ToByteArray();
b[3] |= 0xF0;
return new Guid(b);

这将始终生成以十六进制数字F开头的GUID。

要创建一个不包含任何数字的Guid,您可以使用以下内容:

return new Guid(Guid.NewGuid().ToByteArray()
    .Select(b => (byte)(((b % 16) < 10 ? 0xA : b) | 
                        (((b >> 4) < 10 ? 0xA : (b >> 4)) << 4)))
    .ToArray());

这将测试每个十六进制数字(每个字节两个),如果它小于A,则将其强制转换为A


上述两种解决方案都会生成真正的Guid个对象,尽管增加的限制确实会在一定程度上降低结果GUID的唯一性(在第二个示例中更是如此)。如果你不关心输出是实际的GUID,你可以简单地将十六进制数字重新映射到其他东西,并将结果返回一个字符串,正如其他人所建议的那样。 FWIW,这是我能想到的最短的解决方案:

return String.Concat(Guid.NewGuid().ToString("N").Select(c => (char)(c + 17)));

这会将十六进制数字0到9映射到字符AJ,将十六进制数字A - F映射到字符r w。它还会生成一个没有连字符的字符串。例如:

Before: e58d0f329a2f4615b922ecf53dcd090a
After:  vFIuAwDCJrCwEGBFsJCCvtwFDutuAJAr

当然,如果您不喜欢这里的混合案例,您可以将其转换为大写或小写。

答案 1 :(得分:2)

假设你不需要它是有效的Guid(你引用'某种独特的标识符'),只需创建一个基于字符串的guid(使用Guid.NewGuid().ToString())然后将第一个数字映射到a一系列合适的字母,例如0 = G,1 = H,2 = I等。

答案 2 :(得分:1)

只需编写类似GUID的生成器,有效字符就是a-z(您也可以使用A-Z来增加概率的数量)。

答案 3 :(得分:1)

如何生成一个唯一的数字然后用字母加前缀?而不是

1234

你会用

a1234

只要您为标识符选择的算法保证唯一编号,这应该可以正常工作。如果需要,它还将使您能够去除前缀并再次使用标识符作为数字。

答案 4 :(得分:1)

生成新的GUID,只需将字符0-9替换为字符g-p。

答案 5 :(得分:1)

您可以编写和使用伪随机序列生成器。这是一个提供基本想法的方法:

class RandomLetterSequence { 
    private static Random r; 
    private static char MinChar = (char) 0x0061; 
    private static char MaxChar = (char) 0x007A; 

    public static string RandomSequence() { 
        return RandomSequence(32);  
    }

    public static string RandomSequence(int length) { 
        if (r == null)
            r = new Random(); 
        var sb = new StringBuilder(); 
        for (int i = length; i >= 0; i--) { 
            sb.Append((char)(r.Next(MinChar, MaxChar))); 
        }
        return sb.ToString();
    }
}

通过此实现,可以生成符合您要求的26 ^ 32个可能的不同序列:

  • 类似于碰撞率(无限小)的GUID
  • 仅包含字母

答案 6 :(得分:0)

@ p.s.w.g提供了很好的解决方案。

您可以将他/她的建议写为扩展名:

using System;
using System.Linq;

namespace YourApp.Extensions.GuidExtensions
{
    public static class Extension
    {
        public static Guid FirstLetter(this Guid obj)
        {
            var b = obj.ToByteArray();
            b[3] |= 0xF0;
            return new Guid(b);
        }

        public static Guid OnlyLetters(this Guid obj)
        {
            var ba = obj.ToByteArray();
            return new Guid(
                ba.Select(b => (byte)(((b % 16) < 10 ? 0xA : b) |
                                      (((b >> 4) < 10 ? 0xA : (b >> 4)) << 4)))
                  .ToArray()
            );
        }
    }
}

然后在应用程序中的某处使用它:

// ...
using YourApp.Extensions.GuidExtensions;
// ...

class SomeClass {
    Guid SomeMethodWithFirstLetter() {
        return Guid.NewGuid().FirstLetter();
    }


    Guid SomeMethodWithOnlyLetters() {
        return Guid.NewGuid().OnlyLetters();
    }
}