Add Nibble to an array of bytes - java

I have an array of 9 bytes in Java but my function need to return an array of size 10. The difference I need to pad with Nibbles.
If a nibble is a half of a byte, can I simply add a (byte) 0 to an array at the end or adding 2 nibbles instead will make a difference? Is there a difference between 2 nibbles and a (byte) 0 in this case?

If a nibble is a half of a byte, can I simply add a (byte) 0 to an
array at the end or adding 2 nibbles instead will make a difference?
Is there a difference between 2 nibbles and a (byte) 0 in this case?
No there is no difference since a byte (8 bits) is made up 2 x nibble (4 bits).
Can I even put 8.5 bits into an array of bytes and then check the
array for "length" and get back 8.5 as value?
For 8.5 bits? At this point it will be returned as length of 2 bytes. If you mean 8.5 bytes then it's returned as 9 bytes.
Remember The smallest data-type is a byte not a nibble!! By declaring a type byte (even with no value assigned) you've automatically made 8 bits of 0000 0000. Nibbles just make it easier to visualize the bits within a byte's value (when written in hex notation).
For example the single byte value 0xF0 can be visualised as two nibbles of 1111 0000. Now for a byte 0xBA, if you wanted just one nibble you'll have to make the byte as either 0x0B or 0x0A...
I have an array of 9 bytes in Java but my function need to return an
array of size 10. The difference I need to pad with Nibbles.
Your function returns 80 bits. With 9 bytes you'll have a total 72 bits so you pad with extra 8 bits which means add one byte extra of zero value (eg: 0x00).
In the case of some 8 & half bytes, you should actually create 9 bytes (72bits) but only update the first 68 bits (8.5 bytes).
Best logic is to just declare a byte array with length of 10 (ie: 80 zero bits). Then you can update as many or as few bits as you need within this total allocated space. This way "I have an array of 9 bytes" becomes "I create an array of 10 bytes and only update 9 or even 8.5 bytes" which leaves you with automatic padding of those unused 1 or 1.5 bytes.

So your question is if nibble 0000 adjacent to nibble 0000 equals byte 00000000 ?
Yes.
When you write down the individual bits like that it should be obvious I think.
The need for padding with partial bytes will only arise when you are storing data with partial bytes. For example, let's assume I limited my character set to only a-z, A-Z, 0-9, and the space character. That would enable me to use only 4 bits to encode each character.

Related

Isolating arbitrary bits from a Byte array

In my android app I receive from a sensor data with the size of 8 Byte
via Bluetooth Smart using Android BluetoothGatt. The data contains values for temperature, pressure and humidity. The values are splitted up in the following way.
PRESSURE:
Byte 1 + Byte 2 + first 4 Bits of Byte 3, other 4 bits are 0
TEMPERATURE:
Byte 4 + Byte 5 + first 4 bits of Byte 6, other 4 bits are 0
HUMIDITY:
Byte 7 + Byte 8
Now at the moment I have a Byte Array that contains the 8 Byte.
My Problem is that I don't know how to extract or isolate the bits for temperature, pressure and humidity as described above.
Does anyone have an idea how to solve this?
You need to use bit manipulation operations to extract the values.
For example
int pressure = (byte[0]&0xff)<<16+(byte[1]&0xff)<<8+(byte[2]&0xff)
(the 16s and 8s may need to be 12 and 4 or 0 4 and 12 depending on exactly what it means).
The operations you need are << which shifts the bits inside the byte around and the &0xff which changes the signed byte into a signed integer before you shift it. Otherwise the sign bit will mess things up.

Bit masking java, only showing last 6 bites of a hex

I am playing around on how to manipulate bytes from an inputted Hex number. Data is a Hex:
0x022DA822 == 10001011011010100000100010. After I run the following code:
byte mask= (byte) data;
mask will = 100010, only those last bits. How come it only shows the last 6 bits or 22 in the hex?
Does it mask the first 20 bits by default?
Your cast is causing a loss of data. A byte can hold (you guessed it), one byte of data. Thus the range of a byte is [-128, 127]. Note that the most significant bit is reserved as the sign bit. So basically when you are saying: (byte)data, you are converting your hex data into a variable of type byte, which has a smaller range than your hex string. And thus only the last byte of your data can be stored in the byte.

What is the range of the final character for a Base64 encoded 512 bit digital signature?

I have found through various stack Q&As that a Base64 encoded 256-bit number will have one = for padding and will end only with one of AEIMQUYcgkosw048.
I'm fairly confident that a Base64 encoded 512-bit number will have two ==s of padding because of the bit quotient.
For Base64 encoded 512-bit numbers, what is the range for the final character? The modulus of the quotient of the bits is the same, so does that mean that the final character range is the same for both 256-bit encoded and 512-bit encoded?
This is for space conservation and regexing of readable Ed25519 signatures.
Specifically, I'm converting Java byte[64]s to Stringswith org.apache.commons.codec.binary.Base64's encodeBase64.
I am assuming here that the 256-bit and 512-bit numbers in question are encoded using exactly 32 or 64 bytes respectively (i.e. no dropping of leading zeros, no additional bit to prevent signed/unsigned issues, no ASN.1 BER encoding header, ...).
Base64 uses 4 characters for each byte triple, each character representing 6 bit of the data:
byte #1 | byte #2 | byte #3
bit 7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0
becomes
bit 5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0
char #1 | char #2 | char #3 | char #4
Which char is used for which 6-tupel of bits is specified by means of a table, cf e.g. the Wikipedia article.
Thus, in case of the 256-bit number 32 bytes have to be encoded, i.e. 11 character quadruples are used the last of which only encodes 2 instead of the maximum of 3 bytes, i.e. only 16 bit of data. The last character (for which there is no data), therefore, is a =, and the second to last character (for which there only is data for the top 4 bits) can only be one representing 6-tupels of bits the two lowest bits are 0, i.e. the characters you enumerated.
And in case of the 512-bit number 64 bytes have to be encoded, i.e. 22 character quadruples are used the last of which only encodes 1 instead of the maximum of 3 bytes, i.e. only 8 bit of data. The last two characters (for which there is no data), therefore, are both =, and the second character (for which there only is data for the top 2 bits) can only be one representing 6-tupels of bits the four lowest bits are 0, i.e. the characters AQgw.
As mentioned above, though, I made certain assumptions on the encoding of the numbers...

Cast to byte: how do we clip figures

I'm reading Core Java by Horstmann.
This is an example:
byte nx = (byte)300;
System.out.println(nx);
The result is 44. I can't understand why? I suppose 2 variants: 1) everything is ruined and you just get a complete garbage; 2) there is some logic.
I'm inclined to the second variant as the book tells me that it is 44 that is received. So, there is some algorithm behind it.
Could you help me understand.
A cast to byte will only retain the least significant 8 bits. 300 (as an int here) in binary is
00000000 00000000 00000001 00101100
Retaining the last 8 bits throws away the most signficant 1 (and everything else before it) which represents 256, so the remaining value is 300 - 256 = 44
00101100
The byte data type is only 8 bits long, and the decimal number 300 requires 9 bits.
When you cast it, you truncated it and cut off the leftmost bit, leaving the binary representation of the decimal number 44.
If you need an analogy, think of casting from a float like 35.6 to an int. Because ints cannot have decimal places, that cast truncates '.6' off of the float, ignoring it completely in the returned value.
Look at the binary expansion of 300:
100101100
Now chop off all but the last 8 bits (the width of a byte in Java):
00101100
Now convert that back to an integer value:
44
Note that you have to be careful about sign bits. You can't just take the remainder after dividing by 256. For instance:
byte nx = (byte)400;
System.out.println(nx);
will print -112 (not 144). That's because the bit pattern after the cast is
10010000
and the left-most (eighth) bit is treated as the sign bit in the two's complement representation of -112.

Understanding Java bytes

So at work yesterday, I had to write an application to count the pages in an AFP file. So I dusted off my MO:DCA spec PDF and found the structured field BPG (Begin Page) and its 3-byte identifier. The app needs to run on an AIX box, so I decided to write it in Java.
For maximum efficiency, I decided that I would read the first 6 bytes of each structured field and then skip the remaining bytes in the field. This would get me:
0: Start of field byte
1-2: 2-byte length of field
3-5: 3-byte sequence identifying the type of field
So I check the field type and increment a page counter if it's BPG, and I don't if it's not. Then I skip the remaining bytes in the field rather than read through them. And here, in the skipping (and really in the field length) is where I discovered that Java uses signed bytes.
I did some googling and found quite a bit of useful information. Most useful, of course, was the instruction to do a bitwise & to 0xff to get the unsigned int value. This was necessary for me to get a length that could be used in the calculation for the number of bytes to skip.
I now know that at 128, we start counting backwards from -128. What I want to know is how the bitwise operation works here--more specifically, how I arrive at the binary representation for a negative number.
If I understand the bitwise & properly, your result is equal to a number where only the common bits of your two numbers are set. So assuming byte b = -128, we would have:
b & 0xff // 128
1000 0000-128
1111 1111 255
---------
1000 0000 128
So how would I arrive at 1000 0000 for -128? How would I get the binary representation of something less obvious like -72 or -64?
In order to obtain the binary representation of a negative number you calculate two's complement:
Get the binary representation of the positive number
Invert all the bits
Add one
Let's do -72 as an example:
0100 1000 72
1011 0111 All bits inverted
1011 1000 Add one
So the binary (8-bit) representation of -72 is 10111000.
What is actually happening to you is the following: You file has a byte with value 10111000. When interpreted as an unsigned byte (which is probably what you want), this is 88.
In Java, when this byte is used as an int (for example because read() returns an int, or because of implicit promotion), it will be interpreted as a signed byte, and sign-extended to 11111111 11111111 11111111 10111000. This is an integer with value -72.
By ANDing with 0xff you retain only the lowest 8 bits, so your integer is now 00000000 00000000 00000000 10111000, which is 88.
What I want to know is how the bitwise operation works here--more specifically, how I arrive at the binary representation for a negative number.
The binary representation of a negative number is that of the corresponding positive number bit-flipped with 1 added to it. This representation is called two's complement.
I guess the magic here is that the byte is stored in a bigger container, likely a 32 bit int. And if the byte was interpreted as being a signed byte it gets expanded to represent the same number in the 32 bit int, that is if the most significant bit (the first one) of the byte is a 1 then in the 32 bit int all the bits left of that 1 are also turned to 1 (that's due to the way negative numbers are represented, two's complement).
Now, if you & 0xFF that int you cut off those 1's and end up with a "positive" int representing the byte value you've read.
Not sure what you really want :) I assume you are asking how to extract a signed multi-byte value? First, look at what happens when you sign extend a single byte:
byte[] b = new byte[] { -128 };
int i = b[0];
System.out.println(i); // prints -128!
So, the sign is correctly extendet to 32 bits without doing anything special. The byte 1000 0000 extends correctly to 1111 1111 1111 1111 1111 1111 1000 0000.
You already know how to suppress sign extension by AND'ing with 0xFF - for multi byte values, you want only the sign of the most significant byte to be extendet, and the less significant bytes you want to treat as unsigned (example assumes network byte order, 16-bit int value):
byte[] b = new byte[] { -128, 1 }; // 0x80, 0x01
int i = (b[0] << 8) | (b[1] & 0xFF);
System.out.println(i); // prints -32767!
System.out.println(Integer.toHexString(i)); // prints ffff8001
You need to suppress the sign extension of every byte except the most significant one, so to extract a signed 32-bit int to a 64-bit long:
byte[] b = new byte[] { -54, -2, -70, -66 }; // 0xca, 0xfe, 0xba, 0xbe
long l = ( b[0] << 24) |
((b[1] & 0xFF) << 16) |
((b[2] & 0xFF) << 8) |
((b[3] & 0xFF) );
System.out.println(l); // prints -889275714
System.out.println(Long.toHexString(l)); // prints ffffffffcafebabe
Note: on intel based systems, bytes are often stored in reverse order (least significant byte first) because the x86 architecture stores larger entities in this order in memory. A lot of x86 originated software does use it in file formats, too.
To get the unsigned byte value you can either.
int u = b & 0xFF;
or
int u = b < 0 ? b + 256 : b;
For bytes with bit 7 set:
unsigned_value = signed_value + 256
Mathematically when you compute with bytes you compute modulo 256. The difference between signed and unsigned is that you choose different representatives for the equivalence classes, while the underlying representation as a bit pattern stays the same for each equivalence class. This also explains why addition, subtraction and multiplication have the same result as a bit pattern, regardless of whether you compute with signed or unsigned integers.

Categories