今天reflect组件mscorlib.dll后,看了下Guid的生成算法取哈希值的算法,发现其生成算法是之样生成的:

 

  public struct Guid : IFormattable, IComparable, IComparable<Guid>, IEquatable<Guid>
    {
//私有变量
        private int _a;
        private short _b;
        private short _c;
        private byte _d;
        private byte _e;
        private byte _f;
        private byte _g;
        private byte _h;
        private byte _i;
        private byte _j;
        private byte _k; 


 //构造方法       
       private Guid(bool blank)
        {
            this._a = 0;
            this._b = 0;
            this._c = 0;
            this._d = 0;
            this._e = 0;
            this._f = 0;
            this._g = 0;
            this._h = 0;
            this._i = 0;
            this._j = 0;
            this._k = 0;
            if (!blank)
            {
                this.CompleteGuid();
            }
        }

//....省略无关方法

        [MethodImpl(MethodImplOptions.InternalCall)]
        private extern void CompleteGuid();

        public static Guid NewGuid()
        {
            return new Guid(false);
        }

//....省略无关方法


        public override int GetHashCode()
        {
             return (    (this._a   ^     ((this._b << 0x10) | ((ushort) this._c))    )    ^     ( (this._f << 0x18) | this._k)    );
        }

}


 

 

从上述代码片段来看,生成Guid的算法由外部方法CompleteGuid()提供,因为无法看到源代码,有点遗憾.不过在SourceForge中找到Java写的开源项目JUID用来生Guid.下载下来通过jad工具可以看到其java代码,移植到.net中,可以这样实现以生成GUID:

 

 

 public class JUID
    {
        public static string Generate()
        {
            byte[] uuid1 = new byte[4];
            Random r = new Random();
            r.NextBytes(uuid1);

            byte[] uuid2 = new byte[2];
            r = new Random();
            r.NextBytes(uuid2);

            byte[] uuid3 = new byte[2];
            r = new Random();
            r.NextBytes(uuid3);

            byte[] uuid4 = new byte[2];
            r = new Random();
            r.NextBytes(uuid4);

            byte[] uuid5 = new byte[6];
            r = new Random();
            r.NextBytes(uuid5);

            String juid = asHex(uuid1) + "-" + asHex(uuid2) + "-" + asHex(uuid3) + "-" + asHex(uuid4) + "-" + asHex(uuid5);
            return juid;
        }

        public static String asHex(byte[] buf)
        {
            StringBuilder strbuf = new StringBuilder(buf.Length * 2);

            for (int i = 0; i < buf.Length; i++)
            {
                if ((buf[i] & 0xFF) < 16)
                {
                    strbuf.Append("0");
                }
                
                strbuf.AppendFormat("{0:x}",buf[i] & 0xff);
            }

            return strbuf.ToString();
        }

 

 

JUID移植过来的方法,虽然可以达到生成Guid的目的,但是通过性能测试发现,微软提供的Guid生成算法的速度要比上面移植的算法快,运算100000次,微软的在60ms左右,而上面移植的算法要2900ms左右,慢了近50倍. 如果有高人能够提供微软Guid的生成算法就好了.

 

从上面代码片段里的GetHashCode()方法中可以看出其生成哈希值的方法主要是通过几个私有变量的_b的移位操作,再与_c的按位与操作,再与_a的异或操作,在_f移位和_k按位或操作后,进行异或操作,得到一个或正或负的整型值.

其中用到较多的 ^,<<,|等操作符,比较基础的东西.详见MSDN操作符(http://msdn.microsoft.com/zh-cn/library/6a71f45d.aspx)