Oracle GUIDTORAW和RAWTOGUID函数字节顺序

Dar*_*nke 5 .net oracle guid converter

我的应用程序内部使用通过sys_guid()生成的RAW(16)guids.
最近我开始将我获得guid的Active Directory用户关联起来,格式为:00000000-0000-0000-0000-00000000000

以下两个函数是否正确执行此转换?

找到以下网站:

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;
Run Code Online (Sandbox Code Playgroud)

添加以下站点:

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;
Run Code Online (Sandbox Code Playgroud)

它们来回转换,但我实际上是尊重字节顺序还是有正确的顺序?

Dan*_*rod 5

引用UUID标准:

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文档:

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".
Run Code Online (Sandbox Code Playgroud)

根据维基百科的Endianness文章, Windows 以小端存储数字 - 首先是最不重要的字节.

映射1,2,3,新字节[] {0,1,2,3,4,5,6,7}到"00000001-0002-0003-0001-020304050607",向我们显示数字显示为大然而,如在UUID标准中那样,字节数组以与显示相同的顺序提供 - 不需要交换字节.

所以Guids显示为:

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

在little endian中,这导致字节顺序(byte []不计算为数字,因此:

{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字符串函数是从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);
Run Code Online (Sandbox Code Playgroud)

转置(删除'后'):

{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,11,18,19,20,21,22,23,24,25 ,26,27,28,29,30,31,32}

使用相同的功能(不添加' - ') - 将BE转换为LE,LE转换为BE具有相同的交换,因为字节简单地反转并且反转的反转字节导致非反转字节.