我的应用程序内部使用通过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,3,1,2) || '-' || substr(HexData,11,9,15,13,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,2) || substr(StringData,2) || substr(StringData,4) || substr(StringData,12)); end; END GUIDTORAW;
它们来回转换,但我实际上是尊重字节顺序还是有正确的顺序?
解决方法
引自
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个八位字节,大小和顺序
上面定义的字段,每个字段用Most编码
首先是重要的字节(称为网络字节顺序).请注意
字段名称,特别是多路复用字段,遵循历史记录
实践.
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,new byte[]{0,4,6,7}) creates a Guid that corresponds to "00000001-0002-0003-0001-020304050607".
根据Wikipedia’s Endianness article,Windows以小端存储数字 – >最低有效字节优先.
映射1,新字节[] {0,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,0 – 5,4 – 7,6 – 8,9 – 10,12,14,15}
这导致十六进制字符顺序(每个字节是2个十六进制数字):
{6,1 – 10,8,9 – 14,13 – 16,18,19 – 20,22,23,24,25,26,27,28,29,30,31}
在Oracle中,substr string function是基于1的,因此Oracle字符串索引是:
{7,2 – 11,10 – 15,16,14 – 17,19,20 – 21,31,32}
这导致命令
substr(HexData,2) || substr(HexData,2) || '-' || substr(HexData,4) || '-' || substr(HexData,12);
转置(删除’后’):
{7,10,20,32}
被逆转回来
{1,32}
使用相同的功能(不添加’ – ‘) – 将BE转换为LE,LE转换为BE具有相同的交换,因为字节简单地反转并且反转的反转字节导致非反转字节.