2012-09-06 11 views
5

Ứng dụng của tôi sử dụng nội bộ các định dạng RAW (16) được tạo thông qua sys_guid().
Gần đây tôi đã bắt đầu kết hợp người dùng Active Directory nơi tôi nhận được guid theo định dạng: 00000000-0000-0000-0000-00000000000Oracle GUIDTORAW và chức năng RAWTOGUID endianness

Hai chức năng sau có thực hiện chuyển đổi này chính xác không?

Tìm thấy trang web sau đây:

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; 

Thêm vào trang web sau đây:

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

Came lên với chức năng này để làm nghịch đảo:

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; 

Chúng chuyển đổi qua lại, nhưng tôi có thực sự tôn trọng tính xác thực hoặc có trật tự đúng không?

+0

Tôi đã so sánh kết quả của hàm RAWTOGUID() với phương pháp .NET Guid.ToByteArray(), chèn vào Oracle dưới dạng byte [], chạy RAWTOGUID() vs Guid.ToString() và nhận được kết quả tương tự. Nếu bạn đã thử nghiệm GUIDTORAW() thực sự là ngược lại của RAWTOGUID() thì có vẻ như các hàm đều OK. Tôi sẽ, tuy nhiên, thích đi qua spec của đặt hàng byte của Guid và so sánh với điều đó. –

+0

Related: http://stackoverflow.com/questions/7289734/convert-from-oracles-raw16-to-nets-guid và http://stackoverflow.com/questions/9195551/why-does-guid-tobytearray-order -the-byte-the-way-it-does –

Trả lời

5

Trích dẫn từ UUID standard:

Cấu trúc của UUIDs là:

 
    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 

Trong trường hợp không áp dụng rõ ràng hoặc giao thức trình bày đặc điểm kỹ thuật ngược lại, một UUID được mã hóa như một 128-bit đối tượng, như sau:

các lĩnh vực được mã hóa như 16 octet, với các kích thước và trật tự của lĩnh vực quy định trên, và với mỗi fie ld được mã hóa với hầu hết Byte quan trọng đầu tiên (được gọi là thứ tự byte mạng). Lưu ý rằng các tên trường , đặc biệt đối với các trường ghép kênh, hãy thực hiện theo thực tế lịch sử .

 
    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)       | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 

Trích dẫn từ 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". 

Theo Wikipedia's Endianness article của Windows cửa hàng số trong little endian -> byte trọng số thấp nhất đầu tiên.

Ánh xạ 1,2,3, byte mới [] {0,1,2,3,4,5,6,7} đến "00000001-0002-0003-0001-020304050607", cho chúng ta thấy rằng các số được hiển thị lớn-endian, như trong tiêu chuẩn UUID, tuy nhiên, mảng byte được cung cấp theo thứ tự như hiển thị - không cần phải trao đổi các byte.

Vì vậy Guids được hiển thị như:

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

Trong ít kết quả này theo thứ tự byte (byte [] không được tính là một số như sau:

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

kết quả theo thứ tự thập lục phân (mỗi byte là 2 chữ số thập lục phân):

{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}

Trong Oracle, substr string function là 1-dựa, do đó các chỉ số chuỗi Oracle là:

{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}

những kết quả trong các lệnh

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); 

Và transposed (sau khi loại bỏ '-'s):

{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}

bị đảo ngược trở lại vào

{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ử dụng cùng chức năng (không thêm '-'s) - chuyển đổi BE thành LE và LE thành BE có cùng các hoán đổi vì các byte đơn giản được đảo ngược và đảo ngược các byte được đảo ngược byte được đảo ngược.