Best way to get two nibbles out of a byte in javascript?

后端 未结 3 806
故里飘歌
故里飘歌 2021-02-04 05:57

I\'m parsing a binary file in javascript that is storing two pieces of information per byte, one per nibble. The values are, of course, 0-16 and 0-16.

In all other parts

相关标签:
3条回答
  • 2021-02-04 06:09
    var num = str.charCodeAt(0) & 0xFF;
    var nibble1 = num & 0xF;
    var nibble2 = num >> 4;
    
    0 讨论(0)
  • 2021-02-04 06:19

    You can do:

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

    How does it work?

    Lets suppose the bit representation of num is abcdwxyz and we want to extract abcd as higher nibble and wxyz as lower nibble.

    To extract the lower nibble we just mask the higher nibble by bitwise anding the number with 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.
    

    To extract the higher nibble we first mask the lower nibble by bitwise anding with 0xF0 as:

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

    and then we bitwise right- shift the result right 4 times to get rid of the trailing zeros.

    Bitwise right shifting a variable 1 time will make it loose the rightmost bit and makes the left most bit zero:

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

    Similarly bitwise right shifting 2 times will introduce result in :

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

    and bitwise right shift 4 times gives:

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

    as clearly seen the result is the higher nibble of the byte (abcd).

    0 讨论(0)
  • 2021-02-04 06:22

    Since I'm favoriting this, I wanted to add some things I just wrote that might be useful. Perhaps others will find it useful as well.

    Below's jsFiddle

    Prototypes:


       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;
                                                      };
    



    Example Calls:


       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 ]
       
       
    



    Just added for possible help, but is not used in the above:


    /* 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
    
    0 讨论(0)
提交回复
热议问题