I used the random.nextBytes() method and it generate random bytes. But i want every byte to have a fixed length of 8 bits. How do i do that?
SecureRandom random=new SecureRandom();
byte[] data=new byte[2];
random.nextBytes(data);
System.out.println(Integer.toBinaryString(data[0]));
System.out.println(Integer.toBinaryString(data[1]));
This is the output i get
1000
110010
Thanks
The bytes in the array are already a fixed length of 8 bits. If what you really mean is that you want to print them with a fixed length of 8 bits you can do this:
System.out.println(String.format("%8s", Integer.toBinaryString(data[0] & 0xFF)).replace(' ', '0'));
System.out.println(String.format("%8s", Integer.toBinaryString(data[1] & 0xFF)).replace(' ', '0'));
will print
00001000
00110010
The other suggestions will not work properly for values > 128 (or < 0) unless you add 512 and mask properly, then is is actually nicer:
System.out.println(Integer.toBinaryString((0x100|0xff&data[1]).substring(1))
I am adding this last part, giving credit to Hot Licks since it is the best I have seen. It works with all types accepted by Integer.toBinaryString().
Integer.toBinaryString(0x300+b).substring(2) //for b < 256
If you want a 16 bit result you can do:
Integer.toBinaryString(0x30000+bb).substring(2) //for bb < 65536
Generalized for 1 to 62 bits for n < 2^62:
int bits = 8;
Long mask = (1L << bits) - 1;
Long.toBinaryString((3L << bits) + (mask & n)).substring(2);
63 bits is a special case:
Long.toBinaryString((1L << bits) + (mask & n)).substring(1);
Slightly simpler: Integer.toBinaryString(768+b).substring(2)
I guess this is a difference between binary and decimal. Normally, we think of a byte by definition as having 8 bits. Whereas, an ordinary 8 digit number must start with a non-zero digit (unless it is a business number like an ISBN), an 8-bit byte can start with a 0.
So it seems that you want the most significant bit to be 1 - I think.
Well there is a simple way to "fix" that: number | 128. And it shouldn't harm the randomness.
Related
So I have asmall problem here, and I have no clue what could be wrong.
Thats why I'm asking if this (what I'll show you now) ist correct.
I'm turning Binary Files into Byte Lists, so that I can turn those bytes into half bytes.
For Example:
If I get 96 as decimal number (60 as hexadecimal) I want to get 6 and 0 out of it. The same thing with 127 (hex:7F) - I want to get 7 and 15. To achieve this I wrote the following code:
You'll notice, that I need "unsigned bytes" for this in order to work
System.out.println((byte) ((UnsignedByte.unsignedToBytes(b) - (UnsignedByte.unsignedToBytes(b) % 16)) / 16));
System.out.println((byte) (UnsignedByte.unsignedToBytes(b) % 16));
public static int unsignedToBytes(byte b) {
return b & 0xFF;
}
Am I doing something wrong or is this not a Problem?
Use bit shifting and bitwise operations:
To get the lower four bits, use lowerNibble = wholeByte & 0x0F
To get the upper four bits, use upperNibble = (wholeByte >> 4) & 0x0F
This disregards the sign, because the upper portion of the number is truncated off by & 0x0F.
I am new to bytes and bits and I'm also not very good in maths either. I kind of understand the bitwise operators, but I don't know how to solve math equations/formulas with 2 variables. I'm not sure this is the proper place to ask this but anyway.
I have an formula like this:
(Adr_MSB & 0x3F) << (8 + Adr_LSB)
Now what I want is that I would get an integer (for example 33) and the code would transform it into Adr_MSB and Adr_LSB (which are bytes).
It should work up to 128 (ok I guess it will be 127).
I know that this question might sound dumb or something, but I just don't know enough maths to solve this.
Thanks for all help.
EDIT: By experimenting I figured out, that Adr_MSB is a multiplier (e.g. if it's 10 the result is 10 times biger than if it's 1).
From what I understand
the (Adr_MSB & 0x3F) part of the takes the last six bits of the Adr_MSB and returns corresponding integer.
Eg: 125 (1111101) will return 61 (111101)
Note: This step is removing all bits other than last 6 bits, these bits are lost. Hence Lossless inverse function is not possible.
The (8 + Adr_LSB) just adds 8 to Adr_LSB.
<< is a bit wise Left Shift Operator.
Eg. 61 << 3 = 488 . Since 61 is 111101, adding three zeros to the right (Left Shifting three times) will give 111101000 which is 488.
Effective inverse of the expression (Adr_MSB & 0x3F) << (8 + Adr_LSB) to be applied to given number x
Take first six bits from x and convert it to int. This will be Adr_MSB.
Count the rest of the bits. Subtract 8 from this count and it will be Adr_LSB.
Does the following represent what you are looking for?
((Adr_MSB & 0x3F) << 8) | Adr_LSB
Would this work?
int x = 33;
byte Adr_MSB = (byte)x;
byte Adr_LSB = (byte)24;
System.out.println((Adr_MSB & 0x3F) << (8 + Adr_LSB));
Adr_LSB can also be -8.
Since you do bitwise AND on Adr_MSB and 111111, you have only six consecutive bits available to represent the number, so not all integers can be represented just by shifting those 6 bits. This solution works for x up to , so... you can argue that is not a good solution, but it is a start.
I need to generate a 3-bytes code (like A502F1). I am given a criteria:
1st byte is (serialCodeNumber / (256*256) ) & 0xFF
2nd is (serialCodeNumber / 256) & 0xFF
3th is (serialCodeNumber) & 0xFF
serialCodeNumber is a sequence 1-0xFFF
What does that mean!?
I would generate it like this:
String codeNum = new BigInteger(256, random).toString(16).toUpperCase().substring(0, 6);
But what is the right way of doing it as the requirement says?
I'm not quite sure what is meant by the serialCodeNumber, since if it is later on divided by 65025 it has to be a considerably larger number than 0xFFF (which is 4095) for it to make any reasonable sense.
But let's take a look at the conditions, they would all make sense once you are accustomed to the bitwise AND operator. A good read is available here on how it works but the meat of the matter from that question in my opinion is this sentence by Markus Jarderot:
The result is the bits that are turned on in both numbers.
Since in your conditions you have & 0xFF and 0xFF is 255, or in binary it's 11111111 the first eight bits that are all turned on. This is a neat trick to just retrieve only the first 8 bits of any number. And as we all know 8 bits make up a byte. (Are you starting to see where this all is coming together now?)
As for the conditions before the & 0xFF, some might recognize them as bit shift operations hidden behind divisions.
(serialCodeNumber / (256*256)) is equivalent to (serialCodeNumber >> 16)
and
(serialCodeNumber / 256) is equivalent to (serialCodeNumber >> 8)
But that is not that important in this case.
So the first condition takes the serialCodeNumber divides it by 65025 (256*256) and then looks at the 8 right most bits and ignores any other, from those 8 bits it constructs a byte.
In Java you can pretty much just write the condition as it is:
byte myFirstByte = (byte) ((serialCodeNumber / (256*256)) & 0xFF);
The other conditions aren't much different:
byte mySecondByte = (byte) ((serialCodeNumber / (256)) & 0xFF);
and
byte myThirdByte = (byte) ((serialCodeNumber) & 0xFF);
Once you have all three of your bytes, I'm assuming you need to convert them to a hex String. So I'll add them into a byte array.
byte[] myArray = {myFirstByte,mySecondByte,myThirdByte};
And borrow some method on how to convert byte arrays to HEX strings from this question.
String codeNum = bytesToHex(myArray);
And the result will look something like this:
F03DD7
EDIT:
Since you have to generate a serial number that has to be up to 6 bytes in value, I'd recommend using a long number.
A 6 byte number will be anywhere from 1 to 281474976710655, so you probably need to generate one randomly.
First instantiate a Random object which you will be able to poll numbers from:
Random random = new Random();
Once you have that, poll a long from it for the range 1 to 281474976710655.
For this you can borrow KennyTM's answer from this question.
So you can then generate the number like so:
long serialCodeNumber = nextLong(random, 281474976710655L)+1L;
We add the +1L at the end since we want it to include the last number as well as start from 1 instead of 0.
If you ever need to show a HEX string of the serialCodeNumber you can then just call:
String serialHex = Long.toHexString(serialCodeNumber);
But make sure to add any additional "0"s at the left side based on the length of the string so that it is 6-bytes = 12 characters long.
I have 1 number which require 9 bits and the bits spread into 2 bytes (Most Significant Byte and Least Significant Byte).
The MSB is like:
0?????[Bit8][Bit7]
And the LSB is like:
0[Bit6][Bit5][Bit4][Bit3][Bit2][Bit1][Bit0]
My number consists on 9 bits from Bit0 to Bit8. ? indicates either 1 or 0.
So, how do I get my number?
I can think of shifting the bits in MSB left by 7 bits and then combine it with LSB to form a 16 bit number. However, how can I avoid losing Bit8 when shifting MSB left by 7 bits?
Java bitwise operators are done on 32-bit ints in this case, so you don't lose [bit8] when you shift to the left.
int msb = 0xFF;
int lsb = 0xFF;
int result = ( ( msb & 0x3 ) << 7 ) | ( lsb & 0x7F );
System.out.println(result == 0x1FF);
Additionally , you can try the BitSet class
http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html
for working on arbitrary bit lengths [ example size 9 here]
I have an int and I want to invert the bits of it using the ~ bit operator. This should be a very simply thing to do, however I tried and it doesn't work. I suppose this is because java uses two's complement to represent it's int. So what is the most efficient way to do this? 50 when inverted should be 13 and that's the value I'd like to have
It seems you want only the part of the bitwise complement until the most signifficant set bit of the input. Then you just have to mask the complement,
int invert(int n) {
return ~n & mask(n);
}
int mask(int n) {
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
return n | (n >> 16);
}
Java int is 32-bit long with 1 bit used for sign. Therefore 50 is represented in binary as 00000000000000000000000000110010. If you bit-invert this, you'll get 11111111111111111111111111001101, which is java integer value -51 in decimal notation.
Since an int should be at least 32 bits wide, ~50 is definitely not 13. I think you are assuming the int to be only 8 bits wide, which may have been the case some 237 years ago, but definitely not nowadays and not in Java, anyway. If you need a data type that is guaranteed to be 8 bits wide, use byte.
But even then ~50 is not 13, only if take the least significant 6 bits into account. But all this doesn't have anything to do with two's complement.