Rumah  >  Soal Jawab  >  teks badan

node.js - 如何用代码实现一个小端的16进制字符串(无符号大整数)转化为10进制整数

如题,想要实现如下功能,入参可以是代表16进制的字符串或者一个buffer,是小端的

// return {@string}
function converHexStrToDecStrLittleEnd(strOrBuffer){
    hexToDecLE(strOrBuffer)
}

//test case 
assert(  converHexStrToDecStrLittleEnd('a4fb02129a907c4a') ===  '5367323847320337316' )

求 converHexStrToDecStrLittleEnd 这个函数怎么实现

直接用Buffer.from('a4fb02129a907c4a','hex').readUIntLE(0,8)只能得到5367323847320337000明显是溢出了

======最后结果如下========================================

/**
 * A function for converting hex <-> dec w/o loss of precision.
 *
 * The problem is that parseInt("0x12345...") isn't precise enough to convert
 * 64-bit integers correctly.
 *
 * Internally, this uses arrays to encode decimal digits starting with the least
 * significant:
 * 8 = [8]
 * 16 = [6, 1]
 * 1024 = [4, 2, 0, 1]
 */

// Adds two arrays for the given base (10 or 16), returning the result.
// This turns out to be the only "primitive" operation we need.
function add(x, y, base) {
  var z = [];
  var n = Math.max(x.length, y.length);
  var carry = 0;
  var i = 0;
  while (i < n || carry) {
    var xi = i < x.length ? x[i] : 0;
    var yi = i < y.length ? y[i] : 0;
    var zi = carry + xi + yi;
    z.push(zi % base);
    carry = Math.floor(zi / base);
    i++;
  }
  return z;
}

// Returns a*x, where x is an array of decimal digits and a is an ordinary
// JavaScript number. base is the number base of the array x.
function multiplyByNumber(num, x, base) {
  if (num < 0) return null;
  if (num == 0) return [];

  var result = [];
  var power = x;
  while (true) {
    if (num & 1) {
      result = add(result, power, base);
    }
    num = num >> 1;
    if (num === 0) break;
    power = add(power, power, base);
  }

  return result;
}

function parseToDigitsArray(str, base) {
  var digits = str.split('');
  var ary = [];
  for (var i = digits.length - 1; i >= 0; i--) {
    var n = parseInt(digits[i], base);
    if (isNaN(n)) return null;
    ary.push(n);
  }
  return ary;
}

function convertBase(str, fromBase, toBase) {
  var digits = parseToDigitsArray(str, fromBase);
  if (digits === null) return null;

  var outArray = [];
  var power = [1];
  for (var i = 0; i < digits.length; i++) {
    // invariant: at this point, fromBase^i = power
    if (digits[i]) {
      outArray = add(outArray, multiplyByNumber(digits[i], power, toBase), toBase);
    }
    power = multiplyByNumber(fromBase, power, toBase);
  }

  var out = '';
  for (var i = outArray.length - 1; i >= 0; i--) {
    out += outArray[i].toString(toBase);
  }
  return out;
}

function decToHex(decStr) {
  var hex = convertBase(decStr, 10, 16);
  return hex ? '0x' + hex : null;
}

function hexToDec(hexStr) {
  if (hexStr.substring(0, 2) === '0x') hexStr = hexStr.substring(2);
  hexStr = hexStr.toLowerCase();
  return convertBase(hexStr, 16, 10);
}

function hexToDecLE(hexStr) {
    var len = hexStr.length,arr = [];
    for(var i=len;i>0;i-=2){
        arr.push(hexStr.slice(i-2,i))
    }
    return hexToDec(arr.join(''));
}

hexToDecLE('a4fb02129a907c4a');
PHPzPHPz2763 hari yang lalu635

membalas semua(1)saya akan balas

  • 天蓬老师

    天蓬老师2017-04-17 15:09:25

    js扩展 http://www.danvk.org/hex2dec.html

    /**
     * A function for converting hex <-> dec w/o loss of precision.
     *
     * The problem is that parseInt("0x12345...") isn't precise enough to convert
     * 64-bit integers correctly.
     *
     * Internally, this uses arrays to encode decimal digits starting with the least
     * significant:
     * 8 = [8]
     * 16 = [6, 1]
     * 1024 = [4, 2, 0, 1]
     */
    
    // Adds two arrays for the given base (10 or 16), returning the result.
    // This turns out to be the only "primitive" operation we need.
    function add(x, y, base) {
      var z = [];
      var n = Math.max(x.length, y.length);
      var carry = 0;
      var i = 0;
      while (i < n || carry) {
        var xi = i < x.length ? x[i] : 0;
        var yi = i < y.length ? y[i] : 0;
        var zi = carry + xi + yi;
        z.push(zi % base);
        carry = Math.floor(zi / base);
        i++;
      }
      return z;
    }
    
    // Returns a*x, where x is an array of decimal digits and a is an ordinary
    // JavaScript number. base is the number base of the array x.
    function multiplyByNumber(num, x, base) {
      if (num < 0) return null;
      if (num == 0) return [];
    
      var result = [];
      var power = x;
      while (true) {
        if (num & 1) {
          result = add(result, power, base);
        }
        num = num >> 1;
        if (num === 0) break;
        power = add(power, power, base);
      }
    
      return result;
    }
    
    function parseToDigitsArray(str, base) {
      var digits = str.split('');
      var ary = [];
      for (var i = digits.length - 1; i >= 0; i--) {
        var n = parseInt(digits[i], base);
        if (isNaN(n)) return null;
        ary.push(n);
      }
      return ary;
    }
    
    function convertBase(str, fromBase, toBase) {
      var digits = parseToDigitsArray(str, fromBase);
      if (digits === null) return null;
    
      var outArray = [];
      var power = [1];
      for (var i = 0; i < digits.length; i++) {
        // invariant: at this point, fromBase^i = power
        if (digits[i]) {
          outArray = add(outArray, multiplyByNumber(digits[i], power, toBase), toBase);
        }
        power = multiplyByNumber(fromBase, power, toBase);
      }
    
      var out = '';
      for (var i = outArray.length - 1; i >= 0; i--) {
        out += outArray[i].toString(toBase);
      }
      return out;
    }
    
    function decToHex(decStr) {
      var hex = convertBase(decStr, 10, 16);
      return hex ? '0x' + hex : null;
    }
    
    function hexToDec(hexStr) {
      if (hexStr.substring(0, 2) === '0x') hexStr = hexStr.substring(2);
      hexStr = hexStr.toLowerCase();
      return convertBase(hexStr, 16, 10);
    }

    调用:

    console.log( hexToDec("a4fb02129a907c4a") );
    // "11888097920300383306"
    
    // parseInt会溢出被截短
    console.log( parseInt("a4fb02129a907c4a" ,16));
    // 11888097920300384000

    Python的结果

    print(int("a4fb02129a907c4a", 16))
    # 11888097920300383306

    balas
    0
  • Batalbalas