JavaScript中十六进制字符串到字节值的健壮转换
我尝试从包含十六进制字节表示的字符串中提取字节值。字符串还包含需要忽略的(未知)非十六进制字符(分隔符、空白格式) 给定一个输入字符串“f5 df 45:f8 a 8 f53”,结果将是数组JavaScript中十六进制字符串到字节值的健壮转换,javascript,hex,byte,converter,Javascript,Hex,Byte,Converter,我尝试从包含十六进制字节表示的字符串中提取字节值。字符串还包含需要忽略的(未知)非十六进制字符(分隔符、空白格式) 给定一个输入字符串“f5 df 45:f8 a 8 f53”,结果将是数组[245、223、69、248、168、245]。请注意,字节值仅从两个十六进制数字输出(因此,忽略最后的3) 作为一个附加约束,代码需要在ecmascript 3环境中工作 到目前为止,我使用了这种方法: function parseHex(hex){ hex = hex.replace(/[^0-
[245、223、69、248、168、245]
。请注意,字节值仅从两个十六进制数字输出(因此,忽略最后的3
)
作为一个附加约束,代码需要在ecmascript 3环境中工作
到目前为止,我使用了这种方法:
function parseHex(hex){
hex = hex.replace(/[^0-9a-fA-F]/g, '');
var i,
len = hex.length,
bin = [];
for(i = 0; i < len - 1; i += 2){
bin.push(+('0x' + hex.substring(i, i + 2)));
}
return bin;
}
函数parseHex(hex){
十六进制=十六进制。替换(/[^0-9a-fA-F]/g');
var i,
len=十六进制长度,
bin=[];
对于(i=0;ifunction parseHex(string) {
// remove all non-hex characters, and then separate them into an array in groups of 2 characters
var arr = string.replace(/[^0-9a-fA-F]/g, '').match(/[0-9a-fA-F]{2}/g);
// mutate the array in-place with the correct decimal values
for(var i = 0; i<arr.length; i++) {
arr[i] = parseInt(arr[i], 16);
}
return arr;
}
parseHex('f5 df 45:f8 a 8 f53'); // => [245, 223, 69, 248, 168, 245]
您可以将其设置为如下函数:
function parseHex(string) {
return string.replace(/[^0-9a-fA-F]/g, '').match(/[0-9a-fA-F]{2}/g).map(function(hex) {
return parseInt(hex, 16);
});
}
parseHex('f5 df 45:f8 a 8 f53');
基本上,您可以从字符串中删除非十六进制字符,然后匹配两组十六进制字符(根据您的要求)。描述parseInt(hex,16)
部分(反向为hex.toString(16)
)。TL;博士
使用regex方法会导致代码更少,但性能更差。非正则表达式解决方案提供了更好的性能,但代价是代码稍微多一些
正则表达式方法
经过更多的研究/谷歌搜索(并查看use.match()
),我发现有几种可能的正则表达式方法可以改进原来的方法
直接使用.match()
(不使用.replace()
),灵感来自:
使用.exec()
循环(同样受以下启发):
性能和非正则表达式解决方案
之后,没有一种正则表达式方法的性能明显优于原始方法。出于好奇,我尝试了一个非正则表达式的解决方案,它的性能明显优于其他方法(以稍微多一些代码为代价):
函数parseHex(hex){
var bin=[],i,c,isEmpty=1,buffer;
对于(i=0;i我可能会选择非正则表达式的方法。可能更适合你,因为我在你的帖子中找不到任何问题。@ceving,试图澄清这个问题。@ceving,试图研究是否应该将这个问题发布到codereview,但我还不确信这是离题的。这条特别建议:“请不要以“它属于代码审查”的自定义理由投票结束”,这是一条很好的一行。不幸的是,使用
.map()
对我来说不是一个选项(ES3)。感谢您让我注意到使用.match()
并在适当的位置修改数组。当然,它工作得很好。您对.match()
的使用使我探索了几种正则表达式方法,但后来我发现了一种我更喜欢的非正则表达式方法。
function parseHex(string) {
return string.replace(/[^0-9a-fA-F]/g, '').match(/[0-9a-fA-F]{2}/g).map(function(hex) {
return parseInt(hex, 16);
});
}
parseHex('f5 df 45:f8 a 8 f53');
function parseHex(hex){
hex = hex.match(/[\da-f]/gi);
for(var i = 0; i < hex.length - 1; i += 2){
hex[i >> 1] = +('0x' + hex[i] + hex[i + 1]);
}
hex.length = i >> 1;
return hex;
}
function parseHex(hex){
var bin = [];
hex.replace(/([\da-f])[^\da-f]*([\da-f])/gi,
function(m, digit1, digit2){
bin.push(+('0x' + digit1 + digit2));
}
);
return bin;
}
function parseHex(hex){
var bin = [],
regex = /([\da-f])[^\da-f]*([\da-f])/gi,
result;
while(result = regex.exec(hex)){
bin.push(+('0x' + result[1] + result[2]));
}
return bin;
}
function parseHex(hex){
var bin = [], i, c, isEmpty = 1, buffer;
for(i = 0; i < hex.length; i++){
c = hex.charCodeAt(i);
if(c > 47 && c < 58 || c > 64 && c < 71 || c > 96 && c < 103){
buffer = buffer << 4 ^ (c > 64 ? c + 9 : c) & 15;
if(isEmpty ^= 1){
bin.push(buffer & 0xff);
}
}
}
return bin;
}