我可以将来自java的哈希码与来自javascript的哈希码进行比较吗?

时间:2013-10-01 02:23:03

标签: java javascript ajax hash client-server

我在客户端有一棵树,用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进行散列来比较树木?

1 个答案:

答案 0 :(得分:2)

在Javascript中,原始数字不是32位整数,变量在任何两种类型之间都不会改变;他们总是Numbers

  

Number类型具有18437736874454810627(即264-253 + 3)值,表示IEEE标准二进制浮点运算中指定的双精度64位格式IEEE 754值,但9007199254740990除外(即253-2)IEEE标准的不同“非数字”值在ECMAScript中表示为单个特殊NaN值。

这意味着不同整数的支持范围基本上是-2 53 到2 53

这与Java's double符合的规范相同,因此可以最准确地与之比较。

我不知道你的getMostSignificantBitsAsIntgetLeastSignificantBitsAsInt做了什么,但如果他们解释数字就好了,就好像它是32位整数一样 - 你应该没问题 - - 即使不是。

这可能比它的价值还要多,如果尚未完成和测试,但你可以使用Javascript的bitwise operators来完成它,它将操作数视为32位整数,这正是你在找。 (具体来说,他们的规范要求在应用运算符之前在每个操作数上调用ToInt32。)

我会编写一些方法来使用这些操作数完成此操作,为这些方法编写一些测试用例,并且您的方法应该可行。当然,正如你所说,精度非常重要所以我会单独测试所有部分。


作为最后一点,您还没有说明您的目标是什么,但是您是否可以通过寻找“更小”的身份感来实现您的目标?我不想在有不稳定基础的算法上施加任何压力(关于性能或准确性)。