Dar*_*nke 5 .net oracle guid converter
我的应用程序内部使用通过sys_guid()生成的RAW(16)guids.
最近我开始将我获得guid的Active Directory用户关联起来,格式为:00000000-0000-0000-0000-00000000000
以下两个函数是否正确执行此转换?
找到以下网站:
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)
它们来回转换,但我实际上是尊重字节顺序还是有正确的顺序?
引用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具有相同的交换,因为字节简单地反转并且反转的反转字节导致非反转字节.