2014-01-28 266 views
1

我正在嘗試取uuid並將其轉換回其生成的字節。將UUID轉換爲字節

我一直在研究SecureRandom源,看看我是否可以將UUID反向工程化成字節,但是我很難用它。

我需要做的基本上是這樣的逆:

def self.uuid 
    ary = self.random_bytes(16).unpack("NnnnnN") 
    ary[2] = (ary[2] & 0x0fff) | 0x4000 
    ary[3] = (ary[3] & 0x3fff) | 0x8000 
    "%08x-%04x-%04x-%04x-%04x%08x" % ary 
end 

所以我有這樣的UUID:

"4b6d2066-78ac-49db-b8c4-9f58d8e8842f" 

這開始了與此字符串的字節:

"Km fx\xAC\xC9\xDB\xF8\xC4\x9FX\xD8\xE8\x84/" 

這是什麼軟件包:

[ 
    [0] 1265442918, 
    [1] 30892, 
    [2] 51675, 
    [3] 63684, 
    [4] 40792, 
    [5] 3639116847 
] 

ary[2]ary[3]在修改過的

[ 
    [0] 1265442918, 
    [1] 30892, 
    [2] 18907, 
    [3] 47300, 
    [4] 40792, 
    [5] 3639116847 
] 

所以我原來的UUID分裂背出到其未連接的部分:

[ 
    [0] "4b6d2066", 
    [1] "78ac", 
    [2] "49db", 
    [3] "b8c4", 
    [4] "9f58", 
    [5] "d8e8842f" 
] 

我遇到的問題是我」我不知道這兩條線的倒數是什麼:

ary[2] = (ary[2] & 0x0fff) | 0x4000 
ary[3] = (ary[3] & 0x3fff) | 0x8000 

而且我也不確定如何將其餘元素恢復爲其整數值。我確定它是某種形式的packunpack,但我不確定它需要什麼。

+1

按位'或'(以及'和')不是rev​​ertable,雖然。看看:'ruby -e'放置「#{0x4000 | 0x4000}與#{0x0000 | 0x4000}''#⇒16384與16384'。 – mudasobwa

回答

2

我遇到的問題是我不知道這兩條線的倒數是:

ary[2] = (ary[2] & 0x0fff) | 0x4000 
ary[3] = (ary[3] & 0x3fff) | 0x8000 

這兩行不可逆的......他們正在做的有點算術設置v4(aka random)uuid的版本和變體位,以符合RFC 4122。

http://www.ietf.org/rfc/rfc4122.txt

該數字應符合下列條件:

byte & UUID_CLEAR_VER | UUID_VERSION_4 = byte & b'00001111' | b'01000000' 
byte & UUID_CLEAR_VAR | UUID_VAR_RFC = byte & b'00111111' | b'10000000' 

由於上述線路和RFC可能暗示,你真正想要的是不是這麼多的UUID的字節是其位,訂購逆向工程組件。它確實是一個128位整數,十六進制表示基本上是通過bin2hex傳遞整個事物並重新格式化它,因此它是合理可讀的。

下面是類似的代碼在PHP,一個變化以供參考:

https://github.com/UnionOfRAD/lithium/blob/master/util/String.php#L55

+0

謝謝,這很有道理。我試圖對uuid進行反向工程的原因是,看看我是否試圖比較兩個二進制文件(包括uuid和uuid的計算)是否相同。我得弄清楚別的東西。 – Eugene

+0

這是一個很好的解釋,但是需要在Ruby中的代碼示例 – Tilo

+1

@Tilo:要獲得Ruby版本,請轉換'b'00001111''到'0b00001111'。 (隨意編輯答案。)另外,我不確定你在哪裏看到Eugene要求提供代碼示例。他在問這兩條線是關於什麼的。 –