繁体   English   中英

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

[英]JavaScript - Convert 24 digit hexadecimal number to decimal, add 1 and then convert back?

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

就我而言,这是我的价值

var value = "55a98f19b27585d81922ba0b"

我正在寻找的是

var newValue = "55a98f19b25785d81922ba0c"

我试图为此创建一个函数

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

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

hexPlusOne("eeefab")
=> "eeefac"

但是我的哈希失败了

hexPlusOne(value)
=> "55a98f19b275840000000000"

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

只要输入字符串,此版本将返回一个字符串,因此如果输入类似于“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")); 

此版本可能返回一个字符串,该字符串比输入字符串长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")); 

我很好奇,看看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")); 

该错误来自于尝试将整个24位十六进制值转换为数字,因为它不适合整数范围,JavaScript可以清楚地表示2 在进行此类转换为JavaScript编号时,会丢失一些准确性。

但是,它可以作为多个(例如两个)部分进行处理:如果需要,由于溢出1 ,在右侧部分然后在左侧部分进行数学运算。 (也可以一次处理一个数字,手动完成整个添加。)

每个块的大小可以是12个十六进制数字,这使得它很容易分成两半。


1也就是说,如果右边部分的最终数字大于0xffffffffffff,则只需将一个部分继续(添加)到左边部分。 如果没有溢出,则左侧部分保持不变。

2请参阅什么是JavaScript可以达到的最高整数值而不会丢失精度?

范围为2 ^ 53,但输入值为16 ^ 24~(2 ^ 4)^ 24~2 ^(4 * 24)~2 ^ 96; 仍然是一个有效的数字,但超出了可以清楚表示的整数范围。


此外,使用parseInt(str, 16)而不是在数字上下文中使用"0x" + str来强制转换,因为它使得意图更明确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM