在 JavaScript 中将十六进制数字格式化为短 UUID
Posted
技术标签:
【中文标题】在 JavaScript 中将十六进制数字格式化为短 UUID【英文标题】:Formatting hexadecimal Number to short UUID in JavaScript 【发布时间】:2012-04-12 03:15:02 【问题描述】:我在 javascript 中有一个十六进制数字。出于显示目的,我想将字符串格式化为:
ffffffff-ffff-ffff
00000000-0000-01ff
(8 digits)-(4 digits)-(4 digits)
前面有填充的零
我一直在尝试编写自己的循环来将任意十六进制数格式化为这种格式,但这似乎已经在 JavaScript 中可用。
在 JavaScript 中是否有内置的方式来格式化十六进制数?
【问题讨论】:
遗憾的是,无法在 JavaScript 中格式化此类十六进制数字。但是请查看this link,也许它会有所帮助。 【参考方案1】:我会分两步进行:
1) 将数字转换为带前导零的 16 位十六进制数:
var i = 12345; // your number
var h = ("000000000000000" + i.toString(16)).substr(-16);
2) 添加破折号
var result = h.substr(0, 8)+'-'+h.substr(8,4)+'-'+h.substr(12,4);
【讨论】:
【参考方案2】:进一步了解knabar的答案:
如果您的数字确实是一个完整的 64 位长,您应该知道 javascript 只有双精度数,最高精度约为 53 位。例如
var i = 0x89abcdef01234567; // a 64-bit constant
var h = ("000000000000000" + i.toString(16)).substr(-16); // "89abcdef01234800"
因此,您可能希望将其拆分为两个 32 位数字,并一次将它们格式化为 8 位数字。然后是第二个警告:javascript 对 有符号 32 位整数执行按位运算,并且此格式化代码无法处理负数。
var i = 0xffd2 << 16; // actually negative
var h = ("0000000" + i.toString(16)).substr(-8); // "0-2e0000"
由于您希望格式化为十六进制的数字很可能是按位操作的结果,因此可以调整代码以改为以二进制补码形式打印:
var i = 0xffd2 << 16; // actually negative
var h = ("0000000" + ((i|0)+4294967296).toString(16)).substr(-8); // "ffd20000"
这会生成任意正数和负数整数部分的低 32 位的十六进制表示。这可能是您想要的(大约是printf("%08x")
)。更多极端案例:
var i = 1.5; // non-integers are rounded
var h = ("0000000" + ((i|0)+4294967296).toString(16)).substr(-8); // "00000001"
var i = -1.5; // rounding is towards zero
var h = ("0000000" + ((i|0)+4294967296).toString(16)).substr(-8); // "ffffffff"
var i = NaN; // not actually a number
var h = ("0000000" + ((i|0)+4294967296).toString(16)).substr(-8); // "00000000"
【讨论】:
虽然(i|0)+4294967296
将充分强制数字在范围内且无符号,但i >>> 0
也达到了这个目的,而且也更加清晰。【参考方案3】:
ES6 版本
function toPaddedHexString(num, len)
str = num.toString(16);
return "0".repeat(len - str.length) + str;
var hexStr = toPaddedHexString(12345, 16);
【讨论】:
这由 EMCAScript 2017 中的 padStart 进一步简化。num.toString(16).padStart(len, "0")
【参考方案4】:
String
有两种方法,称为padStart
和padEnd
const num = 15;
console.log(num.toString(16).padStart(2, "0")); // "0f"
const num = 15;
console.log(num.toString(16).padEnd(2, "0")); // "f0"
链接上的其他信息: padStart, padEnd
【讨论】:
【参考方案5】:作为结论的最短版本
对于像00000000-0000-01ff
这样的ID
这是 Adam Leggett 回答的重写和缩短版本。
function createID_8_4_4(s)
return(1e16+s).slice(-16).replace(/^.8|.4(?!$)/g,'$&-')
/*
OR the version for easy understanding:
return(1e16+s).slice(-16).match(/..../g).join('-').replace('-','')
replace on the end replaces only first '-'
*/
console.log(createID_8_4_4('01ff')); //00000000-0000-01ff
对于像0000-0000-0000-01ff
这样的ID
function createID_4_4_4_4(s)
return(1e16+s).slice(-16).match(/..../g).join('-')
console.log(createID_4_4_4_4('01ff')); //0000-0000-0000-01ff
【讨论】:
【参考方案6】:我认为在纯javascript中没有任何相关的东西,但是框架提供了这种方法,在ExtJS 3中它是这样实现的
/**
* Pads the left side of a string with a specified character. This is especially useful
* for normalizing number and date strings. Example usage:
* <pre><code>
var s = String.leftPad('123', 5, '0');
// s now contains the string: '00123'
* </code></pre>
* @param String string The original string
* @param Number size The total length of the output string
* @param String char (optional) The character with which to pad the original string (defaults to empty string " ")
* @return String The padded string
* @static
*/
leftPad : function (val, size, ch)
var result = String(val);
if(!ch)
ch = " ";
while (result.length < size)
result = ch + result;
return result;
【讨论】:
这只是一个填充函数,十六进制格式和破折号呢?【参考方案7】:由于 hexwab 的回答中描述的限制,我假设该数字已经是字符串的形式。如果不是,请使用适合您情况的任何机制将其转换为任意长度的十六进制字符串(称为str
)来启动该过程。那么:
function format(str)
return (1e15+str).slice(-16).match(/^.8|.4/g).join('-');
console.log(format('723e9f4911'))
【讨论】:
非常好的和简短的解决方案! (+) 我从你的回答中写了一个简短的版本。看我的回答。 @Bharata 我喜欢高尔夫!我们开工吧。修改了我的答案。以上是关于在 JavaScript 中将十六进制数字格式化为短 UUID的主要内容,如果未能解决你的问题,请参考以下文章