代码之家  ›  专栏  ›  技术社区  ›  Geuis

在javascript中从一个字节中得到两个半字节的最佳方法是什么?

  •  15
  • Geuis  · 技术社区  · 14 年前

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

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

    但我一直在想如何从我的单字节字符“str”中得到第一个半字节的0-16值,以及第二个半字节的0-16值。

    谢谢你的帮助。

    3 回复  |  直到 14 年前
        1
  •  17
  •   sje397    14 年前
    var num = str.charCodeAt(0) & 0xFF;
    var nibble1 = num & 0xF;
    var nibble2 = num >> 4;
    
        2
  •  15
  •   codaddict    14 年前

    你可以做:

    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次,去掉后面的零。

    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

        3
  •  1
  •   Community kfsone    4 年前

    既然我喜欢这个,我想补充一些我刚刚写的东西,可能会有用。也许其他人也会发现它很有用。

    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