javascript - 在 JavaScript 中转换以 10 为基数和以 255 为基数的整数字符串?

标签 javascript math biginteger bignum

有没有人知道在不使用大数库的情况下转换 JavaScript 中超过 Number.MAX_SAFE_INTEGER 值的 10 进制和 255 进制字符串的方法?

比如:

var base10 = '23456786543234567876543234567876543267';
var base255 = base10ToBase255(base10);

到 base-255 或从 base-255 为:

var base255 = new Uint8Array(20);
for (var i = 0; i < 20; i++) base255[i] = 254 - i;
var base10 = base255ToBase10(base255);

最佳答案

已编辑:更改为允许其他基地 (<=256) 它总是归结为使用一个大整数,抱歉。但您不需要太多,只需大约 100 行代码即可满足您的需求(字符串以 256 为基数并返回)。

"use strict";
var COMMON_BASE = 255; // must be 256 at most!
function copyA(a){
    var ret = new Uint8Array(a.length);
    for(var i = 0;i<a.length;i++){
        ret[i] = a[i];
    }
    return ret;
}

function isZero(a){
    for(var i = 0;i<a.length;i++){
        if(a[i] !== 0)
            return false;
    }
    return true;
}

function clampA(a){
    var alen = a.length;
    var i=0;
    while(a[alen - 1] === 0)alen--;
    var ret = new Uint8Array(alen);
    for(var i = 0;i<alen;i++){
        ret[i] = a[i];
    }
    return ret;
}


function addD(a,d) {
    var tlen = a.length;
    var carry = 0;
    var ret = new Uint8Array(tlen +1);
    if(d === 0)
        return copyA(a);
    var i = 0;
    var temp = carry;
    temp += a[i] + d;
    carry = Math.floor(temp / COMMON_BASE);
    ret[i] = temp % COMMON_BASE;
    for (i = 1; i < tlen; i++) {
        temp = carry;
        temp += a[i];
        carry = Math.floor(temp / COMMON_BASE);
        ret[i] = temp % COMMON_BASE;
    }
    if (carry) {
        ret[i] = carry;
    }

    ret = clampA(ret);
    return ret;
};

function mulD(a,d){
    var tlen = a.length;
    var carry = 0;
    var ret = new Uint8Array(tlen + 1);
    var k = 0;
    var tmp;
    if(isZero(a))
        return copyA(a);
    if(d === 0)
        return new Uint8Array(tlen);
    for (; k < tlen; k++) {
        tmp = a[k] * d + carry;
        ret[k] = tmp % COMMON_BASE;
        carry = Math.floor(tmp / COMMON_BASE);
    }
    if (carry) {
        ret[k] = carry;
    }
    ret = clampA(ret);
    return ret;
}

function divRem(a,d){
      var divrem = function(u, m, v, q, B) {
        var k = 0,
            t;
        for (var j = m - 1; j >= 0; j--) {
            k = (k * COMMON_BASE) ;
            k += u[j];
            if (k >= v) {
                t = Math.floor(k / v);
                k -= t * v;
            } else {
                t = 0;
            }
            q[j] = t;
        }
        return k;
    };
    var Q = new Uint8Array(a.length);
    var R = divrem(a,a.length, d, Q, 8);
    Q = clampA(Q);
    return [Q,R];
}

// Assuming 's' being a string with decimal digits
function base10ToBase256(s){
  var blen = 0;
  // checks&balances omitted
  var out = new Uint8Array(1);
  for(var i=0;i<s.length;i++){
    out = mulD(out,10);
    out = addD(out,parseInt(s[i],10) );
  }
  return out;
}
// Assuming b being a Uint8Array
function base256ToBase10(a){
  var s = "";
  var t = copyA(a);
  var qr = [];
  var i = a.length;
  while(!isZero(t)){
    qr = divRem(t,10);
    s = s + qr[1].toString(10);
    t = qr[0];
  }
  return s.split("").reverse().join("");
}

var str = "8716418673416734167345634096788356249857";
//base10ToBase256(str).join(",");
base256ToBase10(base10ToBase256(str));



var str = "8716418673416734167345634096788356249857";
console.log(base10ToBase256(str).join(","));
console.log(base256ToBase10(base10ToBase256(str)));

此处 LSB 位于零位置。 这是一个粗略的黑客攻击(太多副本等),但它会做到这一点。

关于javascript - 在 JavaScript 中转换以 10 为基数和以 255 为基数的整数字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34486516/

相关文章:

javascript - 将数组值附加到不同的容器

algorithm - 查找具有加权顶点的多边形的质心

c - 如何准确地乘除 64 位整数?

javascript - 如何在特定情况下使用 JavaScript 加载特定的 css 文件?

javascript - 如何在一个页面中渲染多个 angular2 组件?

math - Lisp 中的数组与列表 : Why are lists so much faster in the code below?

arrays - 如何创建二维莫比乌斯带、克莱因瓶和投影平面阵列?

biginteger - perl6 : Cannot unbox 65536 bit wide bigint into native integer

f# - 初始化 BigInteger 的无限列表

javascript - 运行 Node JS 应用程序时如何解决 NPM 代理问题