JavaScript - 将24位十六进制数转换为十进制数,加1然后转换回来?

Ric*_*ton 2 javascript hex largenumber mongodb

对于MongoDB中的ObjectId,我使用24位十六进制数.因为我需要跟踪第二个集合,所以我需要在这个十六进制数字上加1.

就我而言,这是我的价值

var value = "55a98f19b27585d81922ba0b"
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是

var newValue = "55a98f19b25785d81922ba0c"
Run Code Online (Sandbox Code Playgroud)

我试图为此创建一个函数

function hexPlusOne(hex) {
    var num = (("0x" + hex) / 1) + 1;
    return num.toString(16);
}
Run Code Online (Sandbox Code Playgroud)

这适用于较小的十六进制数

hexPlusOne("eeefab")
=> "eeefac"
Run Code Online (Sandbox Code Playgroud)

但是我的哈希失败了

hexPlusOne(value)
=> "55a98f19b275840000000000"
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来解决这个问题?

m69*_*g'' 6

只要输入字符串,此版本将返回一个字符串,因此如果输入类似于"ffffffff",则忽略溢出.

function hexIncrement(str) {
    var hex = str.match(/[0-9a-f]/gi);
    var digit = hex.length;
    var carry = 1;

    while (digit-- && carry) {
        var dec = parseInt(hex[digit], 16) + carry;
        carry = Math.floor(dec / 16);
        dec %= 16;
        hex[digit] = dec.toString(16);
    }
    return(hex.join(""));
}

document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("ffffffffffffffffffffffff"));
Run Code Online (Sandbox Code Playgroud)

此版本可能返回一个字符串,该字符串比输入字符串长1个字符,因为像"ffffffff"这样的输入会变为"100000000".

function hexIncrement(str) {
    var hex = str.match(/[0-9a-f]/gi);
    var digit = hex.length;
    var carry = 1;

    while (digit-- && carry) {
        var dec = parseInt(hex[digit], 16) + carry;
        carry = Math.floor(dec / 16);
        dec %= 16;
        hex[digit] = dec.toString(16);
    }
    if (carry) hex.unshift("1");
    return(hex.join(""));
}

document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("ffffffffffffffffffffffff"));
Run Code Online (Sandbox Code Playgroud)

我很好奇,看看user2864740建议使用12位数字块是否会带来任何好处.令我惊讶的是,即使代码看起来更复杂,它的速度实际上要快两倍.但是第一个版本每秒运行50万次,所以它不像你在现实世界中会注意到的那样.

function hexIncrement(str) {
    var result = "";
    var carry = 1;
    while (str.length && carry) {
        var hex = str.slice(-12);
        if (/^f*$/i.test(hex)) {
            result = hex.replace(/f/gi, "0") + result;
            carry = 1;
        } else {
            result = ("00000000000" + (parseInt(hex, 16) + carry).toString(16)).slice(-hex.length) + result;
            carry = 0;
        }
        str = str.slice(0,-12);
    }
    return(str.toLowerCase() + (carry ? "1" : "") + result);
}

document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("000000000000ffffffffffff") + "<BR>");
document.write(hexIncrement("0123456789abcdef000000000000ffffffffffff"));
Run Code Online (Sandbox Code Playgroud)