JS校验和

我正在尝试反向工程BLE写入以校验和结尾的值(crc8?)

例如:

02FD 1000 2322 4978 0140 00AF 6000 0000 0000 F9 (checksum F9)

02FD 1000 D82E 4F76 0189 00AF FA14 0000 0000 E4 (checksum E4)

有谁知道如何使用JS生成此校验和?

评论
  • bdicta
    bdicta 回复

    JavaScript中的校验和计算 在默认情况下数字为双浮点数的语言中进行整数位数学运算可能会非常困难。您的代码必须确保数字保留为整数,甚至可能保持无符号且在特定的位范围(16位,32位)内。这些额外的步骤可能会使事情复杂化。

    技巧 通过将AND运算符与位掩码一起使用以确保该范围内的所有位,可以使用一些技巧来确保数字是x位整数。例如确保可以通过数字&= 0xffff;完成16位数字。此外,我使用num | 0或num >>> 0,以确保它是一个32位整数(带符号或无符号)。这是必需的,以防止产生负面结果,当您以十六进制显示校验和时,这看起来特别奇怪。

    速度 显然,我没有尝试使用此工具来构建快速的校验和引擎,我只是想在使用SmallPRNG和ISAAC CPRNG笔之后测试按位计算的可能性(正在发布;)。这些算法在所有浏览器和浏览器版本中的执行效果都不同,甚至在某些浏览器中可能会非常慢。我相信Chrome会非常快速地处理数据,并且校验和可以以合理的速度进行计算!

    基类 我将实现多个校验和算法,因此我将创建一个基类,该基类将为所选算法构造状态(ctx)。此状态将跟踪校验和和算法类的实例。该类还将考虑字符串的编码,正确处理字符串。

    此类还包含对Uint8Array支持的测试。我不确定这是否是测试支持的最佳方法,但这确实有用。

    var hasTyped = (function() {
        if(!('Uint8Array' in window)) {
            return false;
        }
    
        try {
            var a = new window.Uint8Array(10);
            a[0] = 100;
            if(a[0] === 100) {
                return true;
            }
            return false;
        } catch (e) {
            return false;
        }
    }());
    

    算法类别 现在我们可以使用Checksum.registerChecksum添加算法。每个Algorithm类应实现一个用于处理数据的数组方法和一个数组方法,以及一个可选的设置方法,该方法将在构造Checksum对象时调用。

    BSD16 这是一个非常简单的代码,此算法只需要一点点代码。 BSD Checksum算法!

    (function() {
        'use strict';
    
        if(typeof(window.Checksum) === "undefined") {
            throw "The Checksum class is required for this code.";
        }
    
        /**
         * Initialize anything you want in the constructor, such as setting up a lookup
         * table of bytes. Make sure to cache your calculations, so they only have to be
         * done once.
         */
        var BSD16 = function BSD16() {
            this.init = 0;
        };
    
        /**
         * bsd16 for arrays, each value must be numeric and will be bound to 8-bits (Int8Array or Uint8Array works best!)
         * @param   {Array}  a input (8-bit array)
         * @param   {Number} p previous checksum state
         * @returns {Number} new checksum state
         */
        BSD16.prototype.array = function(a, p) {
            var c = p || 0, i = 0, l = a.length;
            for(; i < l; i++) c = (((((c >>> 1) + ((c & 1) << 15)) | 0) + (a[i] & 0xff)) & 0xffff) | 0;
            return c;
        };
    
        /**
         * bsd16 for a single value, update a checksum with a new byte
         * @param   {Number} b byte (0-255)
         * @param   {Number} p previous checksum state
         * @returns {Number} new checksum state
         */
        BSD16.prototype.single = function(b, p) {
            var c = p || 0;
            return (((((c >>> 1) + ((c & 1) << 15)) | 0) + (b & 0xff)) & 0xffff) | 0;
        };
    
        Checksum.registerChecksum("bsd16", BSD16);
    }());
    

    FNV32(FNV-0和FNV-1)

    另一个简单的方法是FNV哈希算法-生成32位校验和!

    (function() {
        'use strict';
    
        if(typeof(window.Checksum) === "undefined") {
            throw "The Checksum class is required for this code.";
        }
    
        var prime = 0x01000193;
    
        /**
         * Initialize anything you want in the constructor, such as setting up a lookup
         * table of bytes. Make sure to cache your calculations, so they only have to be
         * done once.
         */
        var FNV32 = function FNV32() {
            this.init = 2166136261; // fnv-1!
        };
    
        /**
         * The setup method which will be called when new Checksum("fletcher", ...) is called.
         * This method is supposed to initialize the checksum cipher and to recieve parameters
         * from the constructor.
         *
         * @param {Number} mode the FNV32 mode (FNV-1 (defualt) or FNV-0)
         */
        FNV32.prototype.setup = function(mode) {
            if(mode === 0) {
                this.init = 0; // fnv-0.
            }
        };
    
        FNV32.prototype.array = function(a, p) {
            var len = a.length,
                fnv = p || this.init;
    
            for(var i = 0; i < len; i++) {
                fnv = (fnv + (((fnv << 1) + (fnv << 4) + (fnv << 7) + (fnv << 8) + (fnv << 24)) >>> 0)) ^ (a[i] & 0xff);
            }
    
            return fnv >>> 0;
        };
    
        FNV32.prototype.single = function(b, p) {
            var fnv = p || this.init;
            return ((fnv + (((fnv << 1) + (fnv << 4) + (fnv << 7) + (fnv << 8) + (fnv << 24)) >>> 0)) ^ (b & 0xff)) >>> 0;
        };
    
        Checksum.registerChecksum("fnv32", FNV32);
    }());
    

    您可以使用此网址阅读全文

    https://codepen.io/ImagineProgramming/post/checksum-algorithms-in-javascript-checksum-js-engine?cf_chl_jschl_tk=39bd0de9934c580b6ce33374feddb9c37ee59c20-1590266531-0-AcdpYddIKyEBHAf0tuLzYDLpqpVAYrXmTKfWqF_3OLQVepxEcJq9z0gjYtxrVssDX487qBCful5gnyyFlqtl1fUzzH-lQXJhSZkUquU7GWLTAWAMbH2st22M1Ef6NxBfdHZKL5K0oLWb7gU88-MWOVWW3Ioponmmm7GVfHqSL7bdGcrSZIWjw_U2hKl57DXPw8YO3eWcykQnewEQPVOV7mQV5MlHPf17K-_Doo9NOoOtFJUQGHZyLJL2ANJAiWP98nK6vBZcIyLh69YUbuYFFgYB7uRmzfnb-NKCFLDbRUTBaq0I6Xr_blRfzAsyen4Jc-7bWN0cvNlKPQzViAxIR68edJx4gYcFIOrJiu-kQmmMQJMcHuwZFuvWCqAYLQEPX63ttncdhJUEXU8ThjhPhiHNPwX4FjzI1PxLRMH8Hoj1GlIur1DyZDxwz-4t64Pwqg