【问题标题】:Best way to get two nibbles out of a byte in javascript?在javascript中从一个字节中取出两个半字节的最佳方法?
【发布时间】:2010-09-21 02:21:31
【问题描述】:

我正在用 javascript 解析一个二进制文件,该文件每个字节存储两条信息,每个半字节一个。值当然是 0-16 和 0-16。

在文件格式的所有其他部分中,每个字节代表一条信息,所以我一直使用以下方法成功获取我需要的数字值:

var num = str.charCodeAt(0) & 0xFF;

但我一直在试图弄清楚如何从我的单字节字符“str”中获取第一个半字节的 0-16 值,以及第二个半字节的值。

感谢您对此的任何帮助。

【问题讨论】:

  • 收藏。我还没有需要,但我可能需要在某些时候使用二进制文件。不过我很好奇你是如何使用它的。
  • 我回来了...我认为值是 0-15,而不是 0-16

标签: javascript byte nibble


【解决方案1】:
var num = str.charCodeAt(0) & 0xFF;
var nibble1 = num & 0xF;
var nibble2 = num >> 4;

【讨论】:

  • 太棒了,谢谢你这么快的回复。我知道 num & 0xF 正在做什么(得到第一个半字节)。你能解释一下>> 4在做什么吗?
  • @Geuis: >> 是“右移”运算符 - 它将字节作为输入并将其向右移动一位(丢弃最低有效位),次数与您指定的一样多右侧,并返回修改后的值。
  • 由于某种原因,这对我不起作用。例如,当使用 str.charCodeAt(0) & 0xFF === 229 转换字节时,我得到较低的“5”和较高的“3966”。
  • 啊,我现在明白为什么了。当我调整您的实现时,我直接从字节中执行 nibble1 和 nibble2 而不首先通过 & 0xFF (它返回整数值)。现在您的解决方案和 codaddict 都在工作。谢谢你们。
【解决方案2】:

你可以这样做:

var num = str.charCodeAt(0);
var lower_nibble = (num & 0xF0) >> 4;
var higher_nibble = num & 0x0F;

它是如何工作的?

假设num 的位表示为abcdwxyz,我们想将abcd 提取为高半字节,将wxyz 提取为低半字节。

要提取低半字节,我们只需将数字与0x0F 逐位与数字相加,即可屏蔽高半字节:

a b c d w x y z
              &
0 0 0 0 1 1 1 1
---------------
0 0 0 0 w x y z  = lower nibble.

为了提取高半字节,我们首先通过与0xF0 进行按位与运算来屏蔽低半字节:

a b c d w x y z
              &
1 1 1 1 0 0 0 0
---------------
a b c d 0 0 0 0

然后我们将结果按位右移 4 次以去除尾随零。

将变量按位右移 1 次将使其最右边的位变松并使最左边的位为零:

a b c d w x y z 
           >> 1
----------------
0 a b c d w x y

类似地按位右移2 次将引入结果:

a b c d w x y z 
           >> 2
----------------
0 0 a b c d w x

按位右移4 次给出:

a b c d w x y z 
           >> 4
----------------
0 0 0 0 a b c d 

正如所见,结果是字节的高半字节 (abcd)。

【讨论】:

  • 你的低和高应该颠倒。二进制从右到左读取。 ASCII:A = DEC:65 = HEX:41,不是HEX:14
  • 没有问题。不错的图表,我认为这对新手很有帮助。
  • @codaddicy:是的,漂亮的 ascii 艺术。也许再一张表格,显示右移的效果,就可以完成这张图片?
【解决方案3】:

由于我喜欢这个,我想添加一些我刚刚写的可能有用的东西。也许其他人也会发现它也很有用。

Below's jsFiddle

原型:


   Number.prototype.fromCharCode  = function ()   {return String.fromCharCode(this);        };

   String.prototype.byte          = function (val){  var a = new Array();                                                         
                                                     for(var i=(val||0),n=val===0?0:this.length-1; i<=n; i++){
                                                        a.push(this.charCodeAt(i) & 0xFF);
                                                     }
                                                     return a;
                                                  };
   
   String.prototype.HiNibble      = function (val){
                                                     var b = this.byte(val);
                                                     var a = new Array();
                                                     for(var i=0,n=b.length-1; i<=n; i++){a.push(b[i] >> 4);}
                                                     return a;
                                                  };

   String.prototype.LoNibble      = function (val){
                                                     var b = this.byte(val);
                                                     var a = new Array();
                                                     for(var i=0,n=b.length-1; i<=n; i++){a.push(b[i] & 0xF);}
                                                     return a;
                                                  };



示例调用:


   var str   = new String("aB");
   console.log(str.byte());             // [ 97, 66 ]
   console.log(str.HiNibble());         // [ 6, 4 ]
   console.log(str.LoNibble());         // [ 1, 2 ]
   
   
   console.log(str.byte(0));            // [ 97 ]
   console.log(str.HiNibble(0));        // [ 6 ]
   console.log(str.LoNibble(0));        // [ 1 ]
   
   var bar = "c";
   console.log(bar.byte());             // [ 99 ]
   console.log(bar.HiNibble());         // [ 6 ]
   console.log(bar.LoNibble());         // [ 3 ]

   var foobar = (65).fromCharCode();    // from an integer (foobar=="A")
   console.log(foobar.byte());          // [ 65 ]
   console.log(foobar.HiNibble());      // [ 4 ]
   console.log(foobar.LoNibble());      // [ 1 ]
   
   



只是为了可能的帮助而添加的,但在上面没有使用:


/* Useful function that I modified
   Originally from: http://www.navioo.com/javascript/dhtml/Ascii_to_Hex_and_Hex_to_Ascii_in_JavaScript_1158.html
*/
   function AscHex(x,alg){
      hex         = "0123456789ABCDEF";
   
      someAscii   = '  !"#$%&\''
                  + '()*+,-./0123456789:;=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\'
                  + ']^_`abcdefghijklmnopqrstuvwxyz{|}';
      r           = "";
      if(alg=="A2H"){
         for(var i=0,n=x.length;i<n;i++){
            let=x.charAt(i);
            pos=someAscii.indexOf(let)+32;
            h16=Math.floor(pos/16);
            h1=pos%16;
            r+=hex.charAt(h16)+hex.charAt(h1);
         }
      }
      if(alg=="H2A"){
         for(var i=0,n=x.length;i<n;i++){
            let1=x.charAt(2*i);
            let2=x.charAt(2*i+1);
            val=hex.indexOf(let1)*16+hex.indexOf(let2);
            r+=someAscii.charAt(val-32);
         }
      }
      return r;
   }
   
   console.log(AscHex('65','A2H'));                // A

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 2023-02-24
    • 2010-09-29
    • 2011-10-19
    • 1970-01-01
    相关资源
    最近更新 更多