Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中十六进制字符串到字节值的健壮转换_Javascript_Hex_Byte_Converter - Fatal编程技术网

JavaScript中十六进制字符串到字节值的健壮转换

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-

我尝试从包含十六进制字节表示的字符串中提取字节值。字符串还包含需要忽略的(未知)非十六进制字符(分隔符、空白格式)

给定一个输入字符串“f5 df 45:f8 a 8 f53”,结果将是数组
[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;i 然而,我认为有可能找到一个更优雅的解决方案,因此问题是:

是否有更好的解决方案来解决此问题(性能更好或代码更少)?

更新答案(ES3) 由于您在对我原始答案的评论中提到您仅限于ES3,因此您应该能够做到这一点:

function 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;i47&&c<58 | c>64&&c<71 | c>96&&c<103){ 缓冲区=缓冲区64?c+9:c)和15; 如果(isEmpty^=1){ 箱子推送(缓冲区和0xff); } } } 返回仓; }
我可能会选择非正则表达式的方法。

可能更适合你,因为我在你的帖子中找不到任何问题。@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;
}