GUID

 

GUID(Globally Unique Identifier)又叫做UUID(Universally Unique Identifier)

GUID是一個128位元長的二進位數,最大可以表示2128(3.4*1038)個,

這是什麼概念?1兆為1012個,所以3.4*1038個可知道是多麼恐怖的數量阿。

全世界的電腦都不會產生重複的GUID值(其實會重複,但機率非常非常低,所以被視為不會重複)。

 

一、格式

GUID是一個128位元長的二進位數,等於16bytes長的二進位數,

4bits可以表示一個十六進位數,所以16bytes長的二進位數等於32個十六進位數,

格式如下

12345678-1234-1234-1234-123456123456

8個十六進位數 - 4個十六進位數 - 4個十六進位數 - 4個十六進位數 - 12個十六進位數

 

二、範例

以下範例示範於C#中如何新增一筆GUID,由MSDN Guid 結構中可看出有五種建構函式

名稱 描述
Guid(Byte[]) 初始化的新執行個體 Guid 使用指定的位元組陣列的結構。
Guid(Int32, Int16, Int16, Byte, Byte, Byte, Byte, Byte, Byte, Byte, Byte) 初始化的新執行個體 Guid 使用指定的整數和位元組結構。
Guid(Int32, Int16, Int16, Byte[]) 初始化的新執行個體 Guid 使用指定的整數和位元組陣列的結構。
Guid(String) 初始化的新執行個體 Guid 結構使用所指定的字串表示的值。
Guid(UInt32, UInt16, UInt16, Byte, Byte, Byte, Byte, Byte, Byte, Byte, Byte) 初始化的新執行個體 Guid 結構,使用指定的不帶正負號整數和位元組。

每一項建構函式示範例如下

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Guid Guid;

            Guid = new Guid(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 });
            //1、04030201-0605-0807-0900-010203040506
            Console.WriteLine("Guid(String):" + Guid.ToString());

            Guid = new Guid(1, 2, 3, 0, 4, 5, 6, 7, 8, 9, 0);
            //2、00000001-0002-0003-0004-050607080900
            Console.WriteLine("Guid(String):" + Guid.ToString());

            Guid = new Guid(1, 2, 3, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
            //3、00000001-0002-0003-0102-030405060708
            Console.WriteLine("Guid(String):" + Guid.ToString());

            Guid = new Guid("fb529bf3170a429fa926a5eb4efd68c1");
            //4、fb529bf3-170a-429f-a926-a5eb4efd68c1
            Console.WriteLine("Guid(String):" + Guid.ToString());

            Guid = new Guid(1, 2, 3, 1, 2, 3, 4, 5, 6, 7, 8);
            //5、00000001-0002-0003-0102-030405060708
            Console.WriteLine("Guid(String):" + Guid.ToString());

            Console.ReadKey();
        }
    }
}

須特別注意第一項建構函式的使用方法,其數值與GUID格式的對應位置有點不太一樣。

 

但如果要保證不會重複也可以做到,就是配合時間來產生GUID值即可。

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("產生五組Guid");
            for (int i = 0; i < 5; i++)
            {
                Guid Guid = GuidComb.Generate();
                Console.WriteLine(Guid);
                Console.ReadLine();
            }

            Console.ReadLine();
        }

        public static class GuidComb
        {
            public static Guid Generate()
            {
                var buffer = Guid.NewGuid().ToByteArray();

                DateTime date_1900 = new DateTime(0x76c, 1, 1); //時間點西元1900年{1900/1/1 上午 12:00:00}
                DateTime dateNow = DateTime.Now; //現在時間點

                TimeSpan spanNow_1900 = new TimeSpan(dateNow.Ticks - date_1900.Ticks); //取得現在時間與西元1900年的時間量
                TimeSpan spanTimeOfDay = dateNow.TimeOfDay; //取得現在時間一天內的時間量

                long daysOfSpan = spanNow_1900.Days; //取得以天為單位的時間量之天數
                long timeOfDay = (long)spanTimeOfDay.TotalMilliseconds; //將一天內的時間量以毫秒為單位列出

                byte[] cDay = BitConverter.GetBytes(daysOfSpan);
                byte[] cTime = BitConverter.GetBytes(timeOfDay);

                //Array.Copy(sourceArray,sourceIndex,destinationArray,destinationIndex,length)
                Array.Copy(cDay, 0, buffer, 4, 2); //將日期天數轉入Guid
                Array.Copy(cTime, 0, buffer, 6, 4); //將時間秒數轉入Guid

                return new Guid(buffer);
            }
        }
    }
}

 

參考資料:

全局唯一識別元

Online GUID Generator

Guid 結構

How to set NewId() for GUID in entity framework