Javascript中的SIP2校验和计算

Javascript中的SIP2校验和计算,javascript,checksum,Javascript,Checksum,我正在开发一个使用SIP2协议()的库系统的REST接口,能够在一个不需要错误纠正的系统上正常工作。但是,我的代码现在正在与另一个需要校验和的系统通信,如规范中所述: 要计算校验和,请将每个字符作为无符号二进制数相加,取总数中较低的16位并执行2的补码。校验和字段是由四个十六进制数字表示的结果 我在这方面做了一些尝试,但不管我做什么,我都无法得到与我的示例消息匹配的校验和。我可能会让这变得比它应该的更难(似乎在一个有适当二进制类型的低级语言中会更容易,等等)。以下是我的最新尝试: var che

我正在开发一个使用SIP2协议()的库系统的REST接口,能够在一个不需要错误纠正的系统上正常工作。但是,我的代码现在正在与另一个需要校验和的系统通信,如规范中所述:

要计算校验和,请将每个字符作为无符号二进制数相加,取总数中较低的16位并执行2的补码。校验和字段是由四个十六进制数字表示的结果

我在这方面做了一些尝试,但不管我做什么,我都无法得到与我的示例消息匹配的校验和。我可能会让这变得比它应该的更难(似乎在一个有适当二进制类型的低级语言中会更容易,等等)。以下是我的最新尝试:

var checksum = 0;
var message = "63AOAA21221021780249|AD9999|AY0AZ";

// add each character as an unsigned binary number
for(var i=0;i<message.length;i++){
    checksum += message[i].charCodeAt();
}

console.log("character sum: " + checksum);

// take the lower 16 bits of the total
checksum = checksum.toString(2);
console.log("character sum binary representation: " + checksum);
while(checksum.length < 16){
    checksum = "0" + checksum;
}
checksum = checksum.substr(0,16);
console.log("lower 16 bits of character total: " + checksum);

// convert to dec
checksum = parseInt(checksum,2);
console.log("checksum dec: " + checksum);

// perform 2's complement
checksum = (checksum  & 0xFFFF) * -1;
console.log("2s complement: " + checksum.toString(2));

// convert to 4 hex digits
checksum = dec2hex(checksum);
console.log("checksum hex: " + checksum);

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
var校验和=0;
var message=“63AOAA21221021780249 | AD9999 | AY0AZ”;
//将每个字符添加为无符号二进制数

对于(var i=0;i我找到了一种方法,它可能不是最优雅的方法,当然也不是高性能的,但它工作可靠

下面是一些其他不幸的灵魂想要回答这个问题的代码。我计划将其与库中其他一些与SIP2相关的位捆绑在一起,但现在这里有一个生成校验和的函数

 function sip2_checksum(message){

    var checksum_int = 0;
    var checksum_binary_string = "";
    var checksum_binary_string_inverted = "";
    var checksum_binary_string_inverted_plus1 = "";
    var checksum_hex_string = "";

    // add each character as an unsigned binary number
    for(var i=0;i<message.length;i++){
            checksum_int += message[i].charCodeAt();
    }

    // convert integer to binary representation stored in a string
    while(checksum_int > 0){
            checksum_binary_string = (checksum_int % 2).toString() + checksum_binary_string;
            checksum_int = Math.floor(checksum_int / 2);
    }

    // pad binary string to 16 bytes
    while(checksum_binary_string.length < 16){
            checksum_binary_string = "0" + checksum_binary_string;
    }

    // invert the binary string
    for(var i=0;i<checksum_binary_string.length;i++){
            var inverted_value = "X"; // something weird to make mistakes jump out
            if(checksum_binary_string[i] == "1"){
                    inverted_value = "0";
            } else {
                    inverted_value = "1";
            }
            checksum_binary_string_inverted += inverted_value;
    }

    // add 1 to the binary string
    var carry_bit = true;
    for(var i=checksum_binary_string_inverted.length - 1;i>=0;i--){
            if(carry_bit){
                    if(checksum_binary_string_inverted[i] === "0"){
                            checksum_binary_string_inverted_plus1 = "1" + checksum_binary_string_inverted_plus1;
                            carry_bit = false;
                    } else {
                            checksum_binary_string_inverted_plus1 = "0" + checksum_binary_string_inverted_plus1;
                            carry_bit = true;
                    }
            } else {
                    checksum_binary_string_inverted_plus1 = checksum_binary_string_inverted[i] + checksum_binary_string_inverted_plus1;
            }
    }

    // convert binary string to hex string and uppercase it because that's what the gateway likes
    checksum_hex_string = parseInt(checksum_binary_string_inverted_plus1,2).toString(16).toUpperCase();

    return checksum_hex_string;
 }
函数sip2\u校验和(消息){
var校验和int=0;
var校验和二进制字符串=”;
var校验和二进制字符串倒置=”;
var校验和二进制字符串倒数加1=“”;
var校验和_十六进制_字符串=”;
//将每个字符添加为无符号二进制数
对于(变量i=0;i 0){
校验和二进制字符串=(校验和整数%2)。toString()+校验和二进制字符串;
校验和int=Math.floor(校验和int/2);
}
//将二进制字符串填充到16字节
while(校验和\u二进制\u字符串长度<16){
校验和二进制字符串=“0”+校验和二进制字符串;
}
//反转二进制字符串
对于(变量i=0;i=0;i--){
if(进位){
if(校验和二进制字符串倒置[i]=“0”){
校验和\u二进制\u字符串\u反向\u plus1=“1”+校验和\u二进制\u字符串\u反向\u plus1;
进位=假;
}否则{
校验和\u二进制\u字符串\u反转的\u plus1=“0”+校验和\u二进制\u字符串\u反转的\u plus1;
进位=真;
}
}否则{
校验和二进制字符串倒数加1=校验和二进制字符串倒数加1+校验和二进制字符串倒数加1;
}
}
//将二进制字符串转换为十六进制字符串并大写,因为这是网关喜欢的
checksum_hex_string=parseInt(checksum_binary_string_inversed_plus1,2).toString(16).toUpperCase();
返回校验和十六进制字符串;
}