为什么 xor 运算符会产生 "No signature of method" 错误消息和/或 bitCount() 需要什么格式才能通过?

Why is the xor operator producing "No signature of method" error message and / or what format does the bitCount() require to be passable?

我一直在尝试将 SQL 函数转换为 Groovy,以便在 Elastisearch 中使用。但是我对 java 和 groovy 的了解是零,我一直在与所有错误作斗争,因为它们来了。

convertFromBaseToBase 工作的第一个问题已解决 。但是现在我遇到了 XOR 运算符的问题。

很有可能,在 xor 部分之后会有更多问题,所以我会 post 前面的完整代码:

public static String convertFromBaseToBase (String str, int fromBase, int toBase){
  return (new BigInteger(str, fromBase)).toString(toBase);
}

def ih_comparehash (String hash_1, String hash_2, int maxlen) { 

    String hashpart1;
    String hashpart2;

    int bitcnt = 0
    int strlen = 16
    int len = 0

    len = hash_1.length() / strlen

    for (i = 0; i < len && i < maxlen; i++) {

        hashpart1 = hash_1.substring((i * strlen) + 1, strlen);
        hashpart2 = hash_2.substring((i * strlen) + 1, strlen);

        cfbtb_1 = convertFromBaseToBase(hashpart1, 16, 10);
        cfbtb_2 = convertFromBaseToBase(hashpart2, 16, 10);

        bitcnt = bitcnt + (cfbtb_1 ^ cfbtb_2).bitCount();
    }

    return ((64 * i) - bitcnt) * 100.0 / (64 * i);
}

System.out.print(ih_comparehash("8f8f87878f8f8080", "50b0f878787a9f97", 1));

Pokable 位于:https://groovyconsole.appspot.com/script/5119420292661248

当前错误:

groovy.lang.MissingMethodException: No signature of method: java.lang.Long.bitCount() is applicable for argument types: () values: []
Possible solutions: bitCount(long)
at Script1.ih_comparehash(Script1.groovy:31)
at Script1$ih_comparehash.callCurrent(Unknown Source)
at Script1.run(Script1.groovy:40)

万一我完全错过了某些东西,这里是 SQL 中的函数,我正在尝试将其转换为 Groovy:

BEGIN
    DECLARE hashpart1 varchar(64) DEFAULT "";
    DECLARE hashpart2 varchar(64) DEFAULT "";
    DECLARE bitcnt int DEFAULT 0;
    DECLARE strlen int DEFAULT 16;
    DECLARE i int DEFAULT 0;
    DECLARE len int DEFAULT 0;

    SET len = LENGTH(hash1) / strlen;

    WHILE i<len AND i < maxlen DO
        SET hashpart1 = SUBSTRING(hash1,(i*strlen)+1,strlen);
        SET hashpart2 = SUBSTRING(hash2,(i*strlen)+1,strlen);
        SET bitcnt = bitcnt + bit_count(cast(conv(hashpart1, 16, 10) as unsigned) ^ cast(conv(hashpart2, 16, 10) as unsigned));
        SET i = i+1;
    END WHILE;

    RETURN ((64*i)-bitcnt)*100.0/(64*i);
END

SQL 代码处理 16 位十六进制数字的块,因为这将表达式中使用的数值的长度限制为 64 位数字。

然后将 16 位十六进制数转换为 base-10,因此它可以转换为 unsigned,执行 XOR 并进行位计数。 XOR 是一个二进制运算,所以 base-10 只用于转换,实际上并不需要,如果 SQL 有一个解析十六进制数的函数。

在Java里面有一个class叫BigInteger(你真的在用)可以处理任意长度的数字,所以都可以这样搞:

public double ih_comparehash(String hash_1, String hash_2, int maxlen) {
    int len = Math.min(hash_1.length() / 16, maxlen);
    BigInteger num1 = new BigInteger(hash_1.substring(0, 16 * len), 16);
    BigInteger num2 = new BigInteger(hash_2.substring(0, 16 * len), 16);
    int bitcnt = num1.xor(num2).bitCount();
    return ((64 * len) - bitcnt) * 100.0 / (64 * len);
}

或等效的 Groovy 代码,如果您愿意的话。