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 of the file format, each byte represents one piece of information, so I have been using the following to successfully get the number values I need:
var num = str.charCodeAt(0) & 0xFF;
But I'm stuck at trying to figure out how to get the 0-16 value of the first nibble, and the same for the 2nd nibble from my single byte character "str".
Appreciate any help on this.
To swap the nibbles, we can use bitwise &, bitwise ” operators. A byte can be represented using a unsigned char in C as size of char is 1 byte in a typical C compiler.
To get the nibbles separately, at first we are taking number into B register as a copy. Now mask upper nibble to get lower nibble and store it, then take the number from B again, mask lower nibble to get upper nibble, then rotate it four times to make it lower order nibble, after that store it to another location.
A full byte (octet) is represented by two hexadecimal digits ( 00 – FF ); therefore, it is common to display a byte of information as two nibbles.
Nibble is half a byte (0-15, or one hex digit). Low nibble are the bits 0-3; high nibble are bits 4-7. Follow this answer to receive notifications.
var num = str.charCodeAt(0) & 0xFF;
var nibble1 = num & 0xF;
var nibble2 = num >> 4;
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
).
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With