2012-09-06 31 views
5

我的應用程序內部使用通過sys_guid()生成的RAW(16)guid。
最近我開始關聯活動目錄用戶,其中我得到的格式爲:00000000-0000-0000-0000-00000000000Oracle GUIDTORAW和RAWTOGUID函數字節順序

以下兩個函數是否正確地進行此轉換?

發現以下網站:

http://www.timvasil.com/blog14/post/2009/01/20/User-defined-function-to-convert-from-RAW(16)-to-a-GUID-in-Oracle.aspx

create or replace 
FUNCTION RAWTOGUID 
(RawData IN RAW 
) RETURN VARCHAR AS 

BEGIN 

declare HexData varchar(32) := rawtohex(RawData); 

begin 
return 
    substr(HexData, 7, 2) 
    || substr(HexData, 5, 2) 
    || substr(HexData, 3, 2) 
    || substr(HexData, 1, 2) 
    || '-' 
    || substr(HexData, 11, 2) 
    || substr(HexData, 9, 2) 
    || '-' 
    || substr(HexData, 15, 2) 
    || substr(HexData, 13, 2) 
    || '-' 
    || substr(HexData, 17, 4) 
    || '-' 
    || substr(HexData, 21, 12); 
end; 

END RAWTOGUID; 

添加在以下站點:

http://dbaspot.com/oracle-server/69226-guid-char-conversion-function.html

想出了這個功能做逆:

create or replace 
FUNCTION GUIDTORAW 
(HexData IN VARCHAR 
) RETURN RAW AS 

BEGIN 

declare StringData varchar(32) := TRANSLATE(HexData,'0{-}','0'); 

begin 

return 
    hextoraw(substr(StringData, 7, 2) 
    || substr(StringData, 5, 2) 
    || substr(StringData, 3, 2) 
    || substr(StringData, 1, 2) 
    || substr(StringData, 11, 2) 
    || substr(StringData, 9, 2) 
    || substr(StringData, 15, 2) 
    || substr(StringData, 13, 2) 
    || substr(StringData, 17, 4) 
    || substr(StringData, 21, 12)); 
end; 

END GUIDTORAW; 

他們來回轉換,但我實際上尊重排序或有正確的順序呢?

+0

我已經使用.NET Guid.ToByteArray()方法將RAWTOGUID()函數的結果與運行RAWTOGUID()vs Guid.ToString()的byte [[]插入到Oracle中並得到了相同的結果。如果您已經測試過GUIDTORAW()確實是RAWTOGUID()的反轉,那麼它看起來好像這些函數都可以。但是,我會更喜歡Guid字節排序的規格並與之比較。 –

+0

相關:http://stackoverflow.com/questions/7289734/convert-from-oracles-raw16-to-nets-guid和http://stackoverflow.com/questions/9195551/why-does-guid-tobytearray-order -the字節僻-IT-做 –

回答

5

UUID standard引用:

的UUID的結構是:

 
    Field     Data Type  Octet Note 
             # 

    time_low    unsigned 32 0-3 The low field of the 
          bit integer   timestamp 

    time_mid    unsigned 16 4-5 The middle field of the 
          bit integer   timestamp 

    time_hi_and_version unsigned 16 6-7 The high field of the 
          bit integer   timestamp multiplexed 
               with the version number 

    clock_seq_hi_and_rese unsigned 8 8  The high field of the 
    rved     bit integer   clock sequence 
               multiplexed with the 
               variant 

    clock_seq_low   unsigned 8 9  The low field of the 
          bit integer   clock sequence 

    node     unsigned 48 10-15 The spatially unique 
          bit integer   node identifier 

在沒有明確的應用程序或表示協議 規範與此相反的,一個UUID被編碼爲一個128位對象, 如下:

該字段編碼爲16個八位字節,其大小和順序爲上面定義的 字段,每個字段使用最高 重要字節首先編碼(稱爲網絡字節順序)。請注意, 字段名稱,特別是對於多路複用字段,遵循歷史 慣例。

 
    0     1     2     3 
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
    |       time_low        | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
    |  time_mid    |   time_hi_and_version | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
    |clk_seq_hi_res | clk_seq_low |   node (0-1)   | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
    |       node (2-5)       | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 

Guid documentation報價:

public Guid(int a, short b, short c, byte[] d) 

Guid(1,2,3,new byte[]{0,1,2,3,4,5,6,7}) 
creates a Guid that corresponds to "00000001-0002-0003-0001-020304050607". 

根據Wikipedia's Endianness article的Windows商店在小尾數 - >至少顯著字節。

映射1,2,3,新字節[] {0,1,2,3,4,5,6,7}到「00000001-0002-0003-0001-020304050607」,向我們顯示數字在UUID標準中顯示爲big-endian,但是,字節數組按照與顯示相同的順序提供 - 不需要交換字節。

所以GUID是顯示爲:

{time_low(4B) - time_mid(2B) - time_hi_and_version(2B) - clock_sq_hi_and_reserved(1B),clock_seq_low(1B) - 節點(6B)}

在小字節序結果爲字節順序(字節[]不計算爲數字,因此:

{3,2,1,0 - 5,4 - 7,6 - 8,9 - 10,11, 12,13,14,15}

這導致十六進制字符順序(每個字節是2個十六進制數字):

{6,7,4,5,2,3,0,1 - 10,11,8,9 - 14,15,12,13 - 16,17,18,19 - 20,21,22 ,23,24,25,26,27,28,29,30,31}

在Oracle中,substr string function是1型,因此在Oracle字符串索引都是:

{7,8,5 ,6,3,4,1,2 - 11,12,9,10 - 15,16,13,14 - 17,18,19,20 - 21,22,23,24,25,26,27,28 ,29,30,31,32}

這導致命令

substr(HexData, 7, 2) 
|| substr(HexData, 5, 2) 
|| substr(HexData, 3, 2) 
|| substr(HexData, 1, 2) 
|| '-' 
|| substr(HexData, 11, 2) 
|| substr(HexData, 9, 2) 
|| '-' 
|| substr(HexData, 15, 2) 
|| substr(HexData, 13, 2) 
|| '-' 
|| substr(HexData, 17, 4) 
|| '-' 
|| substr(HexData, 21, 12); 

並轉置(除去' - '後):

{7,8,5,6,3,4,1,2,11,12,9,10,15,16,13,14,17 ,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}

反轉回

{1,2,3, 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, 29,30,31,32}

使用相同的功能(不添加「-'s) - 轉換BE到LE和LE是具有相同的互換,因爲字節被簡單地反向,並且在非反轉倒車字節結果 - 反轉的字節。