2013-10-01 32 views
1

我有一棵樹在客戶端,在javascript:我可以比較來自java的哈希碼和來自javascript的哈希碼嗎?

function Node(uuid, someData, versionNum) { 
    this.uuid = uuid; 
    this.someData = someData; 
    this.versionNum = versionNum; 
    this.childNodes = []; 
} 

,並在服務器同一棵樹,在Java:

public class Node { 
    UUID uuid; 
    String someData; 
    int versionNum; 
    List<Node> childNodes; 
} 

客戶將發送一個請求到服務器每五秒鐘,要求散列樹。這個想法是樹的哈希值會被遞歸計算如下:

public static long hashSubtree(Node node) { 
    long hash = node.uuid.getMostSignificantBits()^node.uuid.getLeastSignificantBits()^node.versionNum; 
    for (Node childNode : node.childNodes) 
     hash ^= hashSubtree(childNode); 
    return hash; 
} 

在客戶端,一旦接收到來自服務器的響應,與服務器的計算的哈希,客戶端會然後計算自己的哈希公司本地樹:

function hashSubtree(node) { 
    var hash = getMostSignificantBitsAsInt(node.uuid)^getLeastSignificantBitsAsInt(node.uuid)^node.versionNum; 
    for (var i = 0; i < node.childNodes.length; i++) 
     hash ^= hashSubtree(node.childNodes[i]); 
    return hash; 
} 

然後客戶端會比較這兩個哈希碼。如果兩個哈希碼不同,則客戶端與服務器不同步,並且將請求整個樹。

問題:

由於精度是絕對重要的,我需要確保的JavaScript總是在處理整數和從未轉換什麼浮動。假設如果我繼續像這樣使用xor,它會永遠不會變成浮動嗎?

或者,這樣做比使用xor比較樹木的方法更好嗎?

+0

您的Javascript代碼無效。也許你的意思是'var'而不是'long'? – duskwuff

+0

謝謝,修復。我很笨,並沒有嘗試運行它。我現在運行它只是爲了檢查。 – Verdagon

+0

作爲一個方面說明,你會意識到,如果樹中的某些節點在其樹中改變其位置,但不改變它們的UUID;例如兩個節點交換 - 然後這個更改不會顯示在客戶端,對吧? –

回答

2

在Javascript中,原始數字不是32位整數,變量在任何兩種類型之間都不會改變;它們總是Numbers

號碼類型具有完全相同18437736874454810627(即,264-253 + 3)的值,表示雙精度如在IEEE標準二進制浮點指定的64位格式的IEEE 754值-Point算法,但IEEE標準的9007199254740990(即253-2)不同的「非數字」值在ECMAScript中表示爲單個特殊的NaN值。

這意味着對於不同的整數,支持範圍爲基本上至2 。

這與Java's double也符合的規格相同,因此可以將其與此相比進行最準確的比較。

我不知道你getMostSignificantBitsAsIntgetLeastSignificantBitsAsInt做,但你應該罰款,如果他們解釋數,就好像它是一個32位整數 - 儘管事實並非如此。

這可能比它的價值還要多,如果它還沒有完成和測試,但是您可以使用Javascript的bitwise operators來完成它,它將它們的操作數視爲32位整數,這正是您所期待的對於。 (具體來說,他們的規範要求在應用操作符之前調用每個操作數的ToInt32。)

我會寫一些方法來完成這些使用這些操作數,寫這些方法的一些測試用例,你的方法應該工作。當然,正如你所說,精度是非常重要所以我會單元測試所有的部分。


最後一點,你還沒說你的基本目標是什麼,但你可以通過尋找身份的「小」的意義散列實現自己的目標?我不願意在具有不穩定基礎的算法上施加任何形式的壓力(關於性能或準確性)。

+0

謝謝!但是,我怎麼能安全地解釋這個數字,就好像它是一個32位整數,如果它下面是一個雙精度?我不必擔心像epsilons等東西嗎?即使定義了xor也是雙打的? – Verdagon

+0

@Verdagon更新 - 聽起來像按位運算符一樣對待數字,就好像它們是32位運算符一樣,所以它們可能是你的朋友。 – Nicole

+0

真棒,那ToInt32的東西正是我希望他們做的。謝謝! – Verdagon