如何在JavaScript中为BigQuery实现T-SQL CHECKSUM()?

我要寻找的最终结果是在T-SQL CHECKSUM的BigQuery中实现JavaScript UDF。我愿意让C / C ++源代码进行翻译,但是如果有人已经完成了这项工作,那么我很乐意使用它。

或者,如果有人可以想到一种在microsoft SQL Server中存储的字符串与BigQuery中的字符串之间创建等效的哈希码的方法,那么这对我也有帮助。


  • 更新:我已经在注释中通过HABO的链接找到了一些源代码,这些注释以T-SQL编写以执行相同的CHECKSUM,但是我很难将其转换为JavaScript,而JavaScript本质上无法处理64位整数。我正在处理一些小示例,发现该算法仅对 个字节的低字节有效。
  • 更新2:我对复制此算法感到非常好奇,可以看到一些确定的模式,但是我的大脑无法完成将其提炼成反向工程解决方案的任务。我确实发现BINARY_CHECKSUM()CHECKSUM()返回的内容不同,因此前者所做的工作对后者没有帮助。
chengwei8520 回答:如何在JavaScript中为BigQuery实现T-SQL CHECKSUM()?

我花了一天的时间进行反向工程,首先将所有结果转储为单个ASCII字符以及成对的字符。这表明每个字符都有其自己独特的“ XOR代码”,并且字母大小写均相同。此后,该算法非常简单:将左移4位,并通过查找表中存储的代码进行异或运算。

var xorcodes = [
    0,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,33,34,35,36,37,38,39,//  !"#$%&'
    40,41,42,43,44,45,46,47,// ()*+,-./
    132,133,134,135,136,137,138,139,// 01234567
    140,141,48,49,50,51,52,53,54,// 89:;<=>?@
    142,143,144,145,146,147,148,149,// ABCDEFGH
    150,151,152,153,154,155,156,157,// IJKLMNOP
    158,159,160,161,162,163,164,165,// QRSTUVWX
    166,167,55,56,57,58,59,60,// YZ[\]^_`
    142,// abcdefgh
    150,// ijklmnop
    158,// qrstuvwx
    166,61,62,63,64,65,66,// yz{|}~
];

function rol(x,n) {
    // simulate a rotate shift left (>>> preserves the sign bit)
    return (x<<n) | (x>>>(32-n));
}

function checksum(s) {
    var checksum = 0;
    for (var i = 0; i < s.length; i++) {
        checksum = rol(checksum,4);

        var c = s.charCodeAt(i);
        var xorcode = 0;
        if (c < xorcodes.length) {
            xorcode = xorcodes[c];
        }
        checksum ^= xorcode;
    }
    return checksum;
};

有关更多信息,请参见https://github.com/neilodonuts/tsql-checksum-javascript

免责声明:我只在与排序规则设置为VARCHAR的SQL Server中的SQL_Latin1_General_CP1_CI_AS字符串兼容。这不适用于多列或整数,但是我确定基础算法使用相同的代码,因此不难发现。由于归类,它似乎也与db fiddle有所不同:https://github.com/neilodonuts/tsql-checksum-javascript/blob/master/data/dbfiddle-differences.png ...里程可能有所不同!

CHECKSUM tests on SQL Server Express using string literals w/ hyphens

,

fyi,对于那些陷入T-SQL传统模式的人来说,这是一个经过测试的C#实现,对于我一直在使用的大多数字符串/ int来说看起来都很不错:

public static int[] xorcodes = {
    0,// yz{|}~
};


public static int rol(int x,int n) {
    // simulate a rotate shift left (>>> preserves the sign bit)
    return ((int)x << n) | ((int)((uint)x >> (32 - n)));
}

public static int checksum(string s) {
    int checksum = 0; 
    for (var i = 0; i < s.Length; i++) {
        checksum = rol(checksum,4);

        var c = ((int)s[i]);
        int xorcode = 0;
        if (c < xorcodes.Length) {
            xorcode = xorcodes[c];
        } 
        checksum ^= xorcode;
    }
    return checksum;
}
本文链接:https://www.f2er.com/3056190.html

大家都在问