【问题标题】:Elegant way to split hex string at byte 00?在字节 00 处拆分十六进制字符串的优雅方法?
【发布时间】:2019-11-06 18:42:34
【问题描述】:

我需要在每个 00 字节处拆分一个十六进制字符串。我试过这个:

string.split('00');

但这会导致在5009 处发生拆分,例如,这是不正确的,因为它将一个字节分成两半。

换句话说,它会将5009 变成[5, 9],这是我不想要的。但我确实希望它把af0059 变成[af, 59]

是否甚至可以使用正则表达式拆分字节,而不将任何字节切成两半?

我可以使用循环来查找字符串,并且只在偶数索引处划分字符串,但我更喜欢正则表达式。

【问题讨论】:

  • 为什么我的问题会立即被否决?
  • 你不是.split()一个十六进制数字,你是在一个字符串上操作。字符串中有“两个字符”字节的定义。 (我没有对你投反对票)。
  • 我的观点是一个字符串是一个字符串是一个字符串。在 UTF-16 中,每个字符有两个字节,但您指的是每个字节有两个字符(就好像它是一个十六进制数字一样)。
  • 我可以给出一个有点老派的解决方案,但在我理解之前......字符串 IS 填充了十六进制数字,其中每一对都是一个数字,正确?
  • @CocoDaWhiteBerry 我没有专门看它,因为我在发布它时正在挖掘我自己的示例/解决方案。但是,如果解决方案被证明不起作用,您是否不应该取消选中它作为“最终答案”并选中一个? (我不知道 Stackoverflow 是否允许你这样做)

标签: javascript regex string split hex


【解决方案1】:

由于字节大小,你需要先将split字符串转换成字节大小,然后map最后join

const string = "af00b9e00f70";
const res = string.split(/([\d\w]{4})/).filter(e => e).map(e => e.replace(/00([\d\w]{2})/, "$1").replace(/([\d\w]{2})00/, "$1")).join("");
console.log(res);

【讨论】:

  • 没关系。这是行不通的。当我删除 join("") 时,af00b9e00f70 变为 [ 'af', 'b9e0', '0f70' ]。我不希望它把 b9e00f70 分成 2 个单独的字符串。因为这涉及将一对字符分成两半。
【解决方案2】:

也许不是最优雅的,但它确实有效

const inp = "af00b9e00f70"
const out = inp.match(/.{1,2}/g).map(a=>a=="00"?"_":a).join("").split("_");
console.log(out);

【讨论】:

  • 嘿,这正是我正在寻找的那种优雅,这可能是实现我目标的最短代码。效果很好。
【解决方案3】:

这是一个有点“老派”的方法,但它展示了校长。我说“老派”是因为在汇编编码时代我们必须一直这样做。 'string' 包含一长串十六进制对(字节)。在这里,我将其转换为字节值。将“字符串”更改为您想要的任何内容,但请确保它具有偶数个十六进制数字。调用 'translate' 进行演示,并将输出格式化为 alert() (或仅输出到控制台)

var values = []; // output array
var string = "000102030405060708090a0b0c0d0e0f1FFFFEFDFCFBFAF9F8F7F6F5F4F3F2F0";

function getHexByteValues( string) {
    var hex= "0123456789ABCDEF";
    var outIx=0;

    for (var i =0; i <= (string.length-2); i +=2) { // skip every other
        //get higher and lower nibble
         var hexdig1 = string.substring(i, i+1);
         var hexdig0 = string.substring(i+1, i+2);
         // for simplicity, convert alpha to upper case
         hexdig1 = hexdig1.toUpperCase();
         hexdig0 = hexdig0.toUpperCase();

         // convert hex to decimal value.
         // position in lookup string == value
         var dec1 = hex.indexOf(hexdig1);
         var dec0 = hex.indexOf(hexdig0);

         // calc "byte" value, and add to values.
         values[outIx++] = dec1 * 16 + dec0;
        }
    }


function translate(string) {
    getHexByteValues(string);
    var output="";

    for (var i =0; i < values.length; i++)  {
        output += i + " = " + values[i] + "\r\n";
        }
    alert (output);
    }   

【讨论】:

  • 请注意,为了改进对字或 32 位值的调用,您可以添加一个“内部”循环,其限制是半字节/值的数量。或者要转换复杂的结构,其中一串十六进制表示不同偏移量的不同对象大小,您可能需要包含一个“映射”数组,其中每个元素都指示要解析的半字节数。然后,当然,您会遇到知道任何具有 2 个或更多字节的对象的“字节顺序”的老问题。上面的代码可以精简或扩展,但它是一个开始
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 2019-07-27
  • 2015-07-19
  • 1970-01-01
  • 2012-01-24
相关资源
最近更新 更多